3 ms·
Agreed. The writer example was really telling. The whole syntax around using the function changes when you bring the monad into it. Even the placement of the fu
by jamesaguilar 13y ago
Agreed. The writer example was really telling. The whole syntax around using the function changes when you bring the monad into it. Even the placement of the function calls and the data.
- 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.
- deleted 13y ago[deleted]