简体   繁体   中英

Bind non-monadic functions to a monad

Maybe this is an often asked question, but I did not found an answer.

The bind of a monad is defined like that:

(>>=)  :: m a -> (a -> m b) -> m b

At the moment I'm doing this:

foo :: Int
foo = sum $ ((*11) . (+2)) `map` [1..4]

I want to achieve a syntax like this, because I think it's more readable:

[1..4] >>= (+2) >>= (*11) >>= sum

I don't know the right operators instead of >>= .

Besides: foo is 198.

The most readable in this case is certainly

   sum [ (x+2)*11 | x<-[1..4] ]

but if you want it point-free and without extra parens, just rewrite your original line with the infix fmap operator :

   sum $ (*11) . (+2) <$> [1..4]

If you just want to turn the order around, you can replace . with the equivalent flipped operator from Control.Category , and $ with its flipped version eg from lens

   [1..4] & fmap((+2)>>>(*11)) & sum

Then again, if you're after mathematical elegance and want it to "work like a monad", this isn't possible because there's nothing monadic going on here. You could however argue that sum is a Cokleisli arrow in the (not definable, in Haskell 98) Monoid -limited list comonad. We can approximate this by the NonEmpty comonad and write

    extract $ fromList [1..4] =>> (extract>>>(+2)>>>(*11)) =>> sum.toList

but this is ridiculous.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM