7

I understand that following will be:

[(+2),(+1)]<*>[1,2,3] == [3,4,5,2,3,4]

I also understand that fmap is implemented as map. But how could I mentally map this computation in my head? The first time I saw this I assumed the following:

[(*2),(+1)]<*>[1,2,3] == [4,5,6]

The second time around I though about: [[3,4,5],[2,3,4]]. But on the other hand <*> returns an f b so I knew it wouldn't be possible. So my question is, what are the mental steps to make sense out of this?

Rui Peres
  • 25,741
  • 9
  • 87
  • 137

3 Answers3

19

fs <*> xs is more-or-less [f x | f <- fs, x <- xs]. Monads have the Applicative instance

fM <*> xM = do 
  f <- fM
  x <- xM
  return (f x)

which corresponds to the list comprehension pretty directly.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
8

To remember this you might find it easier to simply imagine <*> to be × (Cartesian product):

[a, b, c] × [x, y, z] == [a x, a y, a z, b x, b y, ...]
dfeuer
  • 48,079
  • 5
  • 63
  • 167
Shoe
  • 74,840
  • 36
  • 166
  • 272
1

Interesting. Does an applicative always have to be the cartesian product? Or is the strategy really a matter of choice. For instance could a "zip" of two lists also be valid? ie:

[F1,F2,F3] <*> [a,b,c] == [F1 a, F2 b, F3 c]

Sri
  • 184
  • 2
  • 8