hi all, I'm trying to get my head around functional dependencies
I've created a simplified version of MonadReader
that has no functional dependencies
class MyMonadReader r m where
ask :: m r
When creating instances like
instance Monad m => MyMonadReader Bool (ReaderT r m) where
ask = pure True
instance Monad m => MyMonadReader String (ReaderT r m) where
ask = pure "string"
I see it compiling (as expected) and if I change MyMonadReader
definition to use functional dependencies
class MyMonadReader r m | m -> r where
ask :: m r
The code (as expected) does not compile.
Functional dependencies conflict between instance declarations:
instance Monad m => MyMonadReader Bool (ReaderT r m)
-- Defined at src/Machinery/FunDep.hs:29:10
instance Monad m => MyMonadReader String (ReaderT r m)
-- Defined at src/Machinery/FunDep.hs:31:10
If my instances look following
instance Monad m => MyMonadReader r (ReaderT r m) where -- <---------- THIS ONE WAS ADDED
ask = ReaderT.ask
instance Monad m => MyMonadReader Bool (ReaderT r m) where
ask = pure True
I would expect the code also to not to compile. But it does. And I'm truly puzzled.
Can anyone help with that puzzle? Why it does not complain, with a definition like class MyMonadReader r m | m -> r where
there should be only one instance for ReaderT r m , right?
Here's what I got from FP slack :) https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html?#instance-resolution