Рассмотрите следующую ситуацию. Я определяю функцию для обработки списка элементов типичным способом выполнения операции над головой и вызова функции над остальной частью списка. Но при определенном условии элемента (будучи отрицательным, являясь особым символом, ...), прежде чем продолжить, я меняю знак на остальную часть списка. Как это:Можно ли определить шаблоны композиции в функциях или функторах?
f [] = []
f (x : xs)
| x >= 0 = g x : f xs
| otherwise = h x : f (opposite xs)
opposite [] = []
opposite (y : ys) = negate y : opposite ys
opposite (opposite xs) = xs
Как я стал к ситуации избыточных противоположных операций, накапливая opposite . opposite . opposite ...
.
Это происходит с другими операциями, а не с opposite
, любое такое, что композиция с самим собой идентична, например reverse
.
Возможно ли преодолеть эту ситуацию, используя функторы/монады/аппликативы/стрелки? (Я не очень хорошо понимаю эти концепции). То, что я хотел бы, чтобы иметь возможность определения собственности, или образец композиции, как это:
opposite . opposite = id -- or, opposite (opposite y) = y
для того, чтобы компилятор или интерпретатор избегает вычислить обратное обратное (можно и просто (родной) в некоторых конкатенативных языках).
Звучит как 'картаAccumL'. – user3237465
@ user3237465 ... и 'mapAccumL' является' mapM' для монадии 'State'. И, pow! Мы вернулись в монады. Вопрос только в том, на каком уровне вы абстрагируетесь. «Без монад» может быть хорошо, а может и нет - многое зависит от ваших целей. –
@ Даниэль Вагнер, я думал, что версия с 'mapAccumL' будет проще, но я был [неправильно] (http://ideone.com/TmGEx5). Монадическая версия более описательна. – user3237465