1

I am trying to get my head around the list monad when there is no function specified:

func::[(Int,String)]
func =do
    a <- [1,2,3]
    b <- ["a","b"]
    return (a,b)

I understood that (>>=) ml f=concat (map f ml).Well in our case what is the value of f ?
When i say : a<-[1,2,3] does this get translated to [1,2,3]>>=(\x->return x).
If not why does it not crash since i am not providing any function for the bind operator?

Later Edit

Thanks for your responses , and while i understood what happens with multiple >>= i am more concerned in this simple scenario:

    mym =do
     a<-[1,2,3]
     return a

What is the equivalent ? [1,2,3] >>= (\x -> return x)

Bercovici Adrian
  • 8,794
  • 17
  • 73
  • 152

2 Answers2

7

You do provide a function to the bind function. If we desugar the do notation [Haskell'10 report], we get:

[1,2,3] >>= (\a -> ["a", "b"] >>= (\b -> return (a, b)))

So that means that we here basically get:

concatMap (\a -> ["a", "b"] >>= (\b -> return (a, b))) [1,2,3]

a and thus:

concatMap (\a -> concatMap (\b -> [(a, b)]) ["a", "b"]) [1,2,3]

So we map the [1,2,3] with the given function, and for each element a, we then perform a second concatMap with \b -> [(a, b)]. A concatMap where each element maps to a singleton element, is equivalent to a map, so:

concatMap (\a -> map (\b -> (a, b)) ["a", "b"]) [1,2,3]

which is equivalent to:

concatMap (\a -> [(a, "a"), (a, "b")]) [1,2,3]

and thus:

[(1, "a"), (1, "b"), (2, "a"), (2, "b"), (3, "a"), (3, "b")]

So the do block behind the curtains results in an expression.

EDIT: the equivalent of [1,2,3] >>= (\x -> return x) is:

concatMap (\x -> [x]) [1,2,3]

since (>>=) with the list monad is just flip concatMap, and return is \x -> [x]. We here thus wrap an element in a list, and then concatenate these lists. This is thus equivalent to:

map id [1,2,3]

and thus equivalent to:

[1,2,3]
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
5
do
a <- [1,2,3]
b <- ["a","b"]
return (a,b)

is translated to

[1,2,3] >>= (\a -> do
  b <- ["a","b"]
  return (a,b) )

which is translated to

[1,2,3] >>= (\a ->
  ["a","b"] >>= (\b ->
     return (a,b) ))

Essentially the f function in ml >>= f is "the rest of the do block". There is no standalone translation for a <- [1,2,3], only one within its do block.

You can try to simplify the expression above until you get

[1,2,3] >>= (\a ->
  ["a","b"] >>= (\b ->
     [(a,b)] ))

and then

[1,2,3] >>= (\a ->
  [(a, "a"), (a, "b")])

and then

[(1, "a"), (1, "b"), (2, "a"), (2, "b"), (3, "a"), (3, "b")]
chi
  • 111,837
  • 3
  • 133
  • 218