5 ms·
"half 8 >>= half" might look a lot different from "half . half $ 8", but they're actually identical in underlying structure! The monad version is just using the
by wvs 13y ago
"half 8 >>= half" might look a lot different from "half . half $ 8", but they're actually identical in underlying structure! The monad version is just using the wrong operator for visual comparison.
(.) composes two functions[1] but (>>=) composes a monad value with a monad function[2]. It'd be nice if we had an operator to compose two monad functions instead.
We can define that operator in terms of (>>=): "g <=< f = \x -> f x >>= g". You can check that the types work out[3]. Notice the great similarity to (.). (It's because they're both categorical composition operators of functions.)
Now we can write "half <=< half $ 8" and everything's dandy.
[1]: (.) :: (b -> c) -> (a -> b) -> (a -> c)
[2]: (>>=) :: m a -> (a -> m b) -> m b
[3]: (<=<) :: (b -> m c) -> (a -> m b) -> (a -> m c)
- jamesaguilar 13y agoThis is impressive, but it does not make me want to try Haskell more.
- wvs 13y agoAhaha, I agree. Abstract monad derivations are quite a foreboding introduction.
- tome 13y agoAbsolutely right! (And you preempted my comment at the top level). I think one reason for "monad hell" is unawareness about this kind of composable style.