2013-06-02 4 views
13

Мне было интересно, можно ли выполнять функциональную композицию с функциями, которые принимают более одного аргумента. Я хочу иметь возможность сделать что-то вроде этогоФункциональная композиция с многозначными функциями в haskell?

x = (+3).(*) 

установка x равна функции, которая добавляет три к произведению двух чисел.

+4

http://conal.net/blog/posts/semantic-editor-combinators – luqui

+1

[This] (http://stackoverflow.com/questions/9656797/variadic-compose-function) может быть то, что вы ищете , – is7s

ответ

23

Существует несколько способов сделать это, но все они несколько неудобны.

((+3).) . (*) 
≡ fmap (+3) . (*) 
≡ curry $ (+3) . uncurry (*) 
≡ \l r -> l*r + 3 

Ой, подождите, это была подпись, где есть также компактное определение, думают, что это называется ...

((.).(.)) (+3) (*) 

Я бы утверждать, что решение лямбды, будучи наиболее явными, является а лучше всего здесь.

Что помогает, и это часто делается только на местном уровне, как один (или два) -liner, чтобы определить эту композицию в качестве пользовательского инфиксом:

(.:) :: (c->d) -> (a->b->c) -> a->b->d 
f .: i = \l r -> f $ i l r 

Что позволяет писать просто (+3) .: (*).

Кстати, за аналогичный (b->b->c) -> (a->b) -> a->a->c (Precompose правильной функции как аргументов инфикса) существует a widely-used standard implementation.

+1

Мне нравится '((.). (.))' Лучший, в основном потому, что мне нравится воображать [Frankie Howerd] (http://en.m.wikipedia.org/wiki/Frankie_Howerd), обнаружил его –

+0

+1 для fmap (самый крутой) и лямбда (тот, который мне нужен в любой кодовой базе, над которой я работал!) – monk

+0

да - возьмите лямбду или лучше дайте функции имя - честно говоря: другие решения являются интеллектными, но более или менее нечитабельно (вы можете легко открыть их легко, но я бы сказал, что это нечитаемо) - подобные вещи дают Haskell это ярлык «arcane ebony-tower», который препятствует тому, чтобы многие хорошие разработчики заглядывали в Haskell – Carsten

2

Вы также можете использовать B1 или дрозд комбинатор из Data.Aviary.Birds. Я думаю, что для реальной работы я бы использовал лямбду.

Смежные вопросы