Поэтому у меня есть этот кодтипа ограничения для полиморфных функций, как лифт
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import MonadA
data A = A
newtype MonadA a => MyStateT a b { runMyStateT :: StateT A a b }
deriving (Functor, Applicative, Monad, MonadIO, MonadState A)
instance MonadTrans MyStateT where
lift = MyStateT . lift
и я получаю компилятор жалуется, что не может доказать m
от подписи lift
имеет типа MonadA
или вот как я прочитал эти загадочные ошибки Сообщения.
Could not deduce (MonadA m) arising from a use of `MyStateT'
from the context (Monad m)
bound by the type signature for
lift :: Monad m => m a -> MyStateT m a
есть ли способ справиться с этим? Я думаю, что нужно ограничение, чтобы иметь возможность создать экземпляр следующим образом:
instance MonadA a => MonadA (MyStateT a) where
f = MyStateT . lift . f
Также будет такая реализация f
работы? (Я не получил этого далеко из-за вышеупомянутой ошибки). Я надеюсь, что f
с правой стороны разрешить f
над внутренней монадой a
.
Edit: Это действительно помогло понизить ограничение типа в newtype MonadA a => MyStateT ...
, чтобы избежать точной ошибки, которые я упомянул. Однако там было просто другая ошибка, которую я ранее приписан к тому же, считаю это продолжение примера коды выше (некоторые части повторяются, теперь без ограничений типа):
class MonadB m where
fB :: m()
newtype MyStateT m a = MyStateT { runMyStateT :: StateT A m a}
deriving (... MonadState A ...)
instance MonadTrans MyStateT where
lift = MyStateT . lift
instance MonadA a => MonadA (MyStateT a) where
f = lift . f
instance MonadA a => MonadB (MyStateT a) where
fB = lift (modify (...))
ошибка является
Could not deduce (a ~ StateT A m0) from context (MonadA (MyStateT a), MonadA a)
в реализации fB
. Раньше я пробовал class MonadA m => MonadB m
безрезультатно. Не имеет смысла также сопоставлять a
с StateT A m
. Поскольку MyStateT
является экземпляром MonadState A
, он должен работать, нет?
Edit:
ОК, получил это работает:
fB = MyStateT (modify ...)
глупо меня.