Pergunta

I've been investigating the usage of >>= with lists (when viewed as monads). In an article All about monads I found the following identity for lists: l >>= f = concatMap f l, where l is a list and f is some (unary) function. I tried the simple example of doubling each element of a list and arrived at the following:

let double :: Int -> [Int]
    double = (flip (:) []) . (2*)
let monadicCombination :: [Int]
    monadicCombination = [1,2,3,4,5] >>= double

I specifically wanted the double function to be written in a point-free manner. Can you think of simpler implementations of double so that it still can be used with >>=?

Foi útil?

Solução

Sassa NF's return . (*2) is both short and demonstrates an interesting principle of your example. If we inline the whole thing we'll get

list >>= double
list >>= return . (*2)

The pattern \f l -> l >>= return . f Is common enough to have its own name: liftM

liftM :: Monad m => (a -> b) -> m a -> m b
liftM f m = m >>= return . f

And in fact, liftM is equivalent to fmap, often known as just map when referring to lists:

list >>= return . (*2)
liftM (*2) list
fmap (*2) list
map (*2) list
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top