3 ms·
Monads don’t compose, effects do. ‘IO a’ works great until until you need to add another effect, for example ‘Maybe’. Then you need to bring in monad transforme
by spicebox 3y ago
Monads don’t compose, effects do. ‘IO a’ works great until until you need to add another effect, for example ‘Maybe’. Then you need to bring in monad transformers and create your own monad combining the two, then rewrite all your code to lift the effects from one monad to the other. And you have to do this every time you want to add a new effect.
- ChadNauseam 3y agoNot to mention you need monadic and nonmonadic versions of every higher order function (or so it feels like) - map / mapM, fold / foldM, etc. This is even worse in Rust, which requires you to have a separate implementation for every effect as well (since it doesn't have higher kinded types)
- nyssos 3y ago> Not to mention you need monadic and nonmonadic versions of every higher order function (or so it feels like) - map / mapM This is more a weakness of Haskell's standard library (which is despite its reputation not very friendly to category theory) than an inherent problem with monads. A more general `map` would look something like this class Category c => FunctorOf c f where map :: c a b -> c (f a) (f b) fmap :: FunctorOf (->) f => (a -> b) -> f a -> f b fmap = map type Kleisli m a b = a -> m b mapM :: (Monad m, FunctorOf (Kleisli m) f) => (a -> m b) -> f a -> m (f b) mapM = map type Op c a b = c b a contramap :: FunctorOf (Op (->)) f => (a -> b) -> f b -> f a contramap = map type Product c d (a,x) (b,y) = (c a b, d x y) bimap :: FunctorOf (Product (->) (->)) f => (a -> b, x -> y) -> f (a, x) -> f (b, y) bimap = map -- and so on but this would require somewhat better type-level programming support for the ergonomics to work out.