Ich habe eine sehr nützliche freie Monade aus einem Summen-Datentyp erstellt. Der Abstracts Zugang zu einem persistenten Datenspeicher:MonadError-Instanz für eine freie Monade
data DataStoreF next =
Create Asset (String -> next)
| Read String (Asset -> next)
| Update Asset (Bool -> next)
| UpdateAll [Asset] (Bool -> next)
| Delete Asset (Bool -> next)
| [...] -- etc. etc.
| Error String
type DataStore = Free DataStoreF
würde Ich mag DataStore
eine Instanz von MonadError
mit der Fehlermeldung als (Free (Error str))
behandelt machen:
instance MonadError String DataStore where
throwError str = errorDS str
catchError (Free (ErrorDS str)) f = f str
catchError x _ = x
Aber ich laufe in Overlapping Instanzen Fehler.
Was ist der richtige Weg, um die DataStore
Monade und Instanz von MonadError
zu machen?
Sie können es in einen 'newtype' verpacken und die Instanzen selbst steuern. Ich glaube nicht, dass es einen saubereren Weg dafür gibt. Die Instanzen von 'FreeT' gehen davon aus, dass Sie keine der von anderen Transformers bereitgestellten mtl-Klassen bereitstellen werden. – Cirdec
Wie unterscheidet sich das von der letzten Zeile des ersten Codeblocks? –
@ JohnF.Miller In Ihrem Beispiel ist 'DataStore' nur ein Typ-Alias, kein' NewType', der Ihnen automatisch alle 'Free'-Instanzen liefert. Wenn Sie es jedoch stattdessen als 'newtype' definieren, können Sie' GeneralisierteNeueTypDerivierung' verwenden, um auszuwählen, welche Instanzen Sie erben möchten, und Sie können Ihre eigene 'MonadError'-Instanz definieren. –