haskell - What is the intuitive meaning of "join"? -


what intuitive meaning of join monad?

the monads-as-containers analogies make sense me, , inside these analogies join makes sense. value double-wrapped , unwrap 1 layer. know, monad not container.

how might 1 write sensible, understandable code using join in normal circumstances, when in io?

for list monad, join concat, , concatmap join . fmap. join implicitly appears in list expression uses concat or concatmap.

suppose asked find of numbers divisors of number in input list. if have divisors function:

divisors :: int -> [int] divisors n = [ d | d <- [1..n], mod n d == 0 ] 

you might solve problem this:

foo xs = concat $ (map divisors xs) 

here thinking of solving problem first mapping divisors function on of input elements , concatenating of resulting lists. might think "functional" way of solving problem.

another approch write list comprehension:

bar xs = [ d | x <- xs, d <- divisors x ] 

or using do-notation:

bar xs = x <- xs             d <- divisors             return d 

here might said we're thinking little more imperatively - first draw number list xs; draw divisors divisors of number , yield it.

it turns out, though, foo , bar same function.

morever, these 2 approaches same in any monad. is, monad, , appropriate monadic functions f , g:

do x <- f          y <- g x           same as:    (join . fmap g) f    return y 

for instance, in io monad if set f = getline , g = readfile, have:

do x <- getline    y <- readfile x    same as:   (join . fmap readfile) getline    return y 

the do-block more imperative way of expressing action: first read line of input; treat returned string file name, read contents of file , return result.

the equivalent join expression seems little unnatural in io-monad. shouldn't using in same way used concatmap in first example.