top | item 37249395

(no title)

doyougnu | 2 years ago

Does every usage site have to change? You would alter fibonacci to be:

  fibonacci :: (MonadLogger m, MonadState (Int, Int, Int) m) => m Int
  fibonacci ...
and now of course all callers must support MonadLogger. But instead of using the MonadLogger (or any mtl constraint directly) you should just be constructing an abstraction boundary with a type class synonym:

  class (MonadLogger m, MonadState s m) => MyMonads s m
and now you change fibonacci:

  fibonacci :: MyMonads (Int, Int, Int) m => m Int
  fibonacci ...
And now if you need to add a monad or add Eq or whatever you just have to change your type class synonym rather than every function. Its not a problem with the language its just programing with modularity in mind, even in the type system.

discuss

order

rowanG077|2 years ago

I have seen this in the wild. The result often is that every function has a kitchen sink MyMonads constraint of which it only uses a tiny subset. It's death by a thousand cuts. If you make such a class for every monad combination you get insanely large amount of classes. It's simply unworkable. Which is why you get the kitchen sink monad pattern.

runeks|2 years ago

If you think it's fine that you can log from all functions in other languages, then what's the problem with adding that constraint to all your Haskell functions to allow this?

kccqzy|2 years ago

And what's wrong with the kitchen sink monad pattern? I've certainly used exactly that. And I have no problems with it.