Generalized conclusion of a new type

Haskell can get an instance for MonadState s in T1 below, but not in T2 , which, however, is very type- MonadState s . How should I change the code for T2 so that I can automatically get an instance for MonadState s ?

 {-# LANGUAGE GeneralizedNewtypeDeriving #-} import Control.Monad.Reader import Control.Monad.State newtype T1 rsa = T1 { runT1 :: ReaderT r (State s) a } deriving (Monad, MonadReader r, MonadState s) newtype T2 rsa = T2 { runT2 :: StateT r (State s) a } deriving (Monad, MonadState r, MonadState s) 
+6
source share
1 answer

You cannot have type two instances for MonadState . This is because MonadState is defined as

 class Monad m => MonadState sm | m -> s where get :: ms set :: s -> m () state :: (s -> (a, s)) -> ma 

The key part is | m -> s | m -> s . This requires the extension FunctionalDependencies and it is indicated that for any m we automatically recognize the associated s . This means that for any given m , there can only be one choice for s . So you cannot use it for MonadState rm and MonadState sm , unless r ~ s . If r ~ s , then how does the compiler know which base monad it applies to? In this case, I think you will also find that it will be much easier to understand and work with the code if you create get and put functions that have suffixes to indicate which ones, for example getInner , setInner and getOuter , setOuter .

+7
source

Source: https://habr.com/ru/post/974902/


All Articles