How to apply a traversable of functions to a one value

178 Views Asked by At

What should I use if I want to have something like

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

basically I have a list of functions, all take in a value a and returns b. I want to apply all of them to one a and get the results [b].

Which one should I use?

Thanks

3

There are 3 best solutions below

5
Joseph Sible-Reinstate Monica On

You don't need Traversable, just Functor:

swingMap f x = fmap ($ x) f

See also the swing function (this is equivalent to swing fmap).


Or, if you're using Edward Kmett's distributive library, you can have the best of both this answer (only a Functor rather than a Traversable) and chi's answer (avoiding defining a custom function for the job), by using distribute from Data.Distributive.

7
chi On

You could use sequence, specialized to the (->) a monad. In this way you can avoid defining a custom function for the job -- it's already there.

> :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 and traverse id, being the same, would also work)

3
Redu On

When functions appear in a data type it's time to remember applicatives because that's what it is. One might easily do this job like;

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

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