Ich habe die folgende Newtype-Deklaration. Es wird ein Monad-Stack-Transformator umwickelt, der einige Standard-MTL-Monaden wie Reader und Except stapelt.
newtype TrxDbFileBased f a = TrxDbFileBased {
unTrxDbFileBased :: ExceptT TrxDbError (ReaderT TrxDbFileBasedEnv f) a
} deriving (
Functor
, Applicative
, Monad
, MonadError TrxDbError
, MonadReader TrxDbFileBasedEnv
, MonadIO
, MonadTrans
)
data TrxDbFileBasedEnv = TrxDbFileBasedEnv {
workingDirectory :: FilePath
} deriving (Show)
data TrxDbError = TrxDbErrorIO TrxDbFileBasedEnv IOException
| TrxDbErrorStr TrxDbFileBasedEnv String
deriving (Show)
Ich möchte, dass dieser Newtype eine Instanz von ist MonadTrans
, erhalte jedoch den folgenden Fehler.
• Can't make a derived instance of ‘MonadTrans TrxDbFileBased’
(even with cunning GeneralizedNewtypeDeriving):
cannot eta-reduce the representation type enough
• In the newtype declaration for ‘TrxDbFileBased’
|
31 | , MonadTrans
| ^^^^^^^^^^
Ich verstehe nicht, warum MonadTrans
nicht abgeleitet werden kann, da der zugrunde liegende Typ ExceptT
eine Instanz von ist MonadTrans
.
Das Problem ist, dass, wenn diese Ableitung funktioniert, Ihre Instanz von MonadTrans
den Funktor transformieren würde f
, während die Instanz für ExceptT
, von der Sie erwarten, dass sie als Basis der Ableitung verwendet wird, die Monade transformiert ReaderT TrxDbFileBasedEnv f
.
Diese sind nicht repräsentativ äquivalent, GeneralizedNewtypeDeriving
können Ihnen also hier nicht helfen.
Hier ist eine andere Möglichkeit, darüber nachzudenken: Versuchen Sie, die Klasse manuell zu implementieren. Wenn Sie das versuchen, werden Sie sehen, dass Ihr lift
Wille wie folgt definiert werden muss:
lift = TrxDbFileBased . lift . lift
Das heißt, zunächst Hebt f
in ReaderT
, dann Anheben ReaderT
in ExceptT
und dann alles in Einwickeln TrxDbFileBased
. GND erwartet jedoch nichts weiter als das No-Op-Wrapping, was bedeutet, dass das Methodenwörterbuch direkt wiederverwendet wird, da die Typen repräsentativ äquivalent sind. Dies ist in Ihrem Fall nicht der Fall.
Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.
Bei Verstößen wenden Sie sich bitte [email protected] Löschen.
Lass mich ein paar Worte sagen