Как применить обходные функции к одному значению - PullRequest
1 голос
/ 10 марта 2020

Что я должен использовать, если я хочу иметь что-то вроде

[a->b] -> a -> [b]

, в основном у меня есть список функций, все принимают значение a и возвращают b. Я хочу применить их все к одному a и получить результаты [b].

Какой я должен использовать?

Спасибо

Ответы [ 3 ]

10 голосов
/ 10 марта 2020

Вам не нужно Traversable, просто Functor:

swingMap f x = fmap ($ x) f

См. Также swing функция (это эквивалентно swing fmap).


Или, если вы используете Edward Kmett distributive library , вы можете получить лучший из обоих ответов (только Functor вместо Traversable) и ответа Чи (избегая определения пользовательской функции для задания), используя distribute из Data.Distributive .

6 голосов
/ 10 марта 2020

Вы можете использовать sequence, специализированный для монады (->) a. Таким образом, вы можете избежать определения пользовательской функции для задания - она ​​уже есть.

> :t sequence
sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)
> :t sequence :: [a->b] -> a -> [b]
sequence :: [a->b] -> a -> [b] :: [a -> b] -> a -> [b]
> sequence [id,(10+),(10-)] 3
[3,13,7]

(sequenceA и traverse id, будучи одинаковыми, также будут работать)

1 голос
/ 10 марта 2020

Когда функции появляются в типе данных, пора вспомнить аппликативы, потому что это так. Можно легко сделать эту работу, как;

appList :: [a->b] -> a -> [b]
appList fs x = fs <*> pure x

λ> appList [(+1), (*2), subtract 3] 5
[6,10,2]
...