Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell Applicative idiom?

Tags:

idioms

haskell

I'm new to Haskell and am puzzling over how to best express some operations in the most idiomatic and clear way. Currently (there will be more to come) I'm puzzling over <*> (I'm not even sure what to call that).

For example, if I have, say

f = (^2)
g = (+10)

as representative functions (in practice they are more complex, but the key thing here is that they are different and distinct), then

concatMap ($ [1,2,3,4,10]) [(f <$>), (g <$>) . tail . reverse] 

and

concat $ [(f <$>), (g <$>) . tail . reverse] <*> [[1,2,3,4,10]]

accomplish the same thing.

Is one of these more idiomatic Haskell, does one imply something an experienced reader of Haskell that the other does not. Perhaps there are additional (better) ways to express exactly the same thing. Are there conceptual differences between the two approaches that a novice Haskeller like myself may be missing?

like image 865
orome Avatar asked Sep 09 '15 14:09

orome


1 Answers

Both your functions (f <$>) and (g <$>).tail.reverse return a monoid type (list in this case) so you can use mconcat to convert them into a single function. Then you can apply this function directly to the input list instead of wrapping it in another list and using concatMap:

mconcat [(f <$>), (g <$>).tail.reverse] $ [1,2,3,4,10]

To expand on this, a function a -> b is an instance of Monoid if b is a monoid. The implementation of mappend for such functions is:

mappend f g x = f x `mappend` g x

or equivalently

mappend f g = \x -> (f x) `mappend` (g x)

so given two functions f and g which return a monoid type b, fmappendg returns a function which applies its argument to f and g and combines the results using the Monoid instance of b.

mconcat has type Monoid a => [a] -> a and combines all the elements of the input list using mappend.

Lists are monoids where mappend == (++) so

mconcat [(f <$>), (g <$>).tail.reverse]

returns a function like

\x -> (fmap f x) ++ (((fmap g) . tail . reverse) x)
like image 97
Lee Avatar answered Sep 20 '22 20:09

Lee