MonadBaseControl IO ... StateT Implementation

I am trying to figure out how to implement a MonadBaseControl instance for type Foo, which is the newtype wrapper around the StateT instance. You think this will be implemented in the same way as, but it does not seem to be. I assume that part of the state is causing the problem here, so is there a way to reset it?

code:

newtype Foo a = Foo { unFoo :: StateT Int IO a } 
                deriving (Monad, Applicative, Functor, MonadBase IO)

instance MonadBaseControl IO Foo where
   type StM Foo a = a 
   liftBaseWith f = Foo $ liftBaseWith $ \q -> f (q . unFoo)
   restoreM = Foo . restoreM 

Mistake:

 Couldn't match type ‘a’ with ‘(a, Int)’
 ‘a’ is a rigid type variable bound by
 the type signature for restoreM :: StM Foo a -> Foo a
  Expected type: a -> StateT Int IO a  
 Actual type: StM (StateT Int IO) a -> StateT Int IO a
 Relevant bindings include
 restoreM :: StM Foo a -> Foo a
 In the second argument of ‘(.)’, namely ‘restoreM’
  In the expression: Foo . restoreM
+4
source share
1 answer

To avoid UndecidableInstances, the linked answer expanded the type family, which for human readability really shouldn't have. Namely, he writes

instance MonadBaseControl IO Foo where
    type StM Foo a = a

when you can consider the entry instead

instance MonadBaseControl IO Foo where
    type StM Foo a = StM (ReaderT Int IO) a

, . ( UndecidableInstances) . UndecidableInstances, , ; ghci, :

> :kind! forall a. StM (StateT Int IO) a
forall a. StM (StateT Int IO) a :: *
= (a, Int)

, StateT Foo :

instance MonadBaseControl IO Foo where
    type StM Foo a = (a, Int)
+8

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


All Articles