Betrachten Sie das folgende SnippetWillkürliche Monade Transformator Stapel in Variable vom Typ
import Control.Monad.Trans
import Control.Monad.Trans.Except
import Control.Monad.Trans.State
newtype MyTransT m a = MyTransT (m a)
foo :: (MonadTrans t, Monad (t (Either e))) => MyTransT (t (Either e)) a -> a
foo = undefined
bar :: MyTransT (StateT Int (Either e)) a
bar = undefined
baz :: MyTransT (StateT Int (StateT Int (Either e))) a
baz = undefined
x = foo bar -- works
y = foo baz -- doesn't work
Im Wesentlichen Ich versuche, eine Funktion zu erstellen, die einen Stapel Monade Transformators akzeptiert, mit der Ober- und Unterseite des Stapels angegeben, während der Mitte kann alles sein.
Nach meinem Kopf für eine Weile kratzen, warum foo baz
mit Couldn't match type ‘StateT Int (Either e1)’ with ‘Either e0’
abgelehnt wurde, es kam schließlich zu mir, dass in diesem Fall war ich davon aus, dass t
StateT Int (StateT Int)
war das nicht nicht nur ein MonadTrans
, es ist nicht richtig getippt/kinded.
Gibt es eine Möglichkeit, das zu erreichen, was ich versuche, oder ist es an der Zeit, einen anderen Ansatz zu wählen?
Können Sie einige konkrete Beispiele dafür geben, wie Sie 'foo' in der Praxis anwenden können? – ErikR
Stellen Sie sich vor Sie haben einen Typ 'T', der an einen Container vom Typ' V' mit Schlüsseln vom Typ 'K' gedacht werden kann. Stellen Sie sich nun vor, dass jedes 'V' ebenfalls diesem Muster folgt. Ich hätte gerne 'foo :: StateT V (t (Entweder e)) a -> StateT T (ReaderT K (t (Entweder e))) a '. Dies würde zustandsorientierte Operationen über "V" erfordern und sie in zustandsbehaftete Operationen über "T" bringen, die eine Umgebung mit "K" haben. Im Grunde eine Baumstruktur, die ich unendlich nach oben und unten verlängern kann, ohne den bestehenden Code zu ändern. – user2085282
Konkrete Beispiele wären hier hilfreicher. Und zögern Sie nicht, es in Ihre Frage zu stellen, wo es leichter zu lesen ist. – ErikR