2016-02-01 2 views
1

Можно ли манипулировать вложенными функциональными композициями в Haskell таким образом, чтобы некоторая обработка выполнялась перед каждой функцией перед композицией?Haskell Вложенные функции компостирования

Предположим, что вложенная композиция, например, (lines . unlines . words) "Testing Haskell composition" (это не имеет смысла, это просто случайный пример). Я хотел бы сделать что-то перед выполнением lines, unlines и words. Что-то вроде этого поддельного кода:

performComposition :: [functions] -> returnValue 
performComposition [] =() 
performComposition (f:fs) = do something 
          f (performComposition fs) 

Возможно ли, даже если необходимо создать новый оператор?

EDIT (17 февраля 2016)

я не упомянул, что я хотел сделать что-то другое на последней функции. В приведенном выше примере функция words сделает что-то отличное от других, прежде чем выполнять ее.

Решение, которое я нашел, подробно описано ниже.

+0

вы можете написать свой собственный * композиция * оператор - но 'делать something' часть пахнет ... – Carsten

+1

побочных эффектов Вы можете быть немного более конкретный в вашем примере? Для чего вы хотите использовать это? Какую проблему вы пытаетесь решить, которую нельзя решить, просто используя что-то вроде 'run before computation after = before >> return computation >> = (\ val -> after >> return val)'? Это монадическая функция, поэтому она не может использоваться вместо «вычисления». – bheklilr

+0

Wait: вы хотите это: 'performComposition [] = id; executeComposition (f: fs) = f. Выполнить функцию fs'? Но это просто обобщает композицию на список функций (это 'fold'). – Bakuriu

ответ

0

Аналогичный вопрос с несколькими ответами можно найти here. Насколько я понимаю, механизм расщепления функциональных композиций отсутствует. Вы могли бы добавить какую-то конструкцию (более подробную информацию в ссылке), но она нарушила бы функциональную чистоту haskells, поскольку функция декомпозиции должна обеспечивать разные результаты с помощью разных правил композиции a=f.(g.h) и b=(f.g).h. (но его та же функция, которая делает то же самое преобразование, поэтому он должен возвращать то же самое каждый раз)

+2

Это выглядит как комментарий. И если вы считаете, что вопрос является дубликатом, вы должны проголосовать/флаг за дублирование. – Bakuriu

1

Решение, которое я нашел в моей проблеме, состояло в том, чтобы создать нечто похожее на тернарный оператор. This link был необходим.

Таким образом, простая демонстрация решения моей проблемы:

(>=>) :: a -> (a->b) -> b -- first operator 
x >=> y = doSomething1 --fake code 
      y x 

(¨¨) :: a -> (a->b) -> b -- second operator 
x ¨¨ y = doSomething2 --fake code 
     y x 

infixl 0 >=> 
infixl 1 ¨¨ 

times2 :: Int -> Int 
times2 x = x*2 

plus2 :: Int -> Int 
plus2 x = x+2 

plus3 :: Int -> Int 
plus3 x = x+3 

main = putStrLn $ show (3 ¨¨ plus2 ¨¨ times2 >=> plus3) 
Смежные вопросы