Я создал очень полезную бесплатную Monad из типа данных суммы. Это тезисы доступ к постоянному хранилищу данных:Экземпляр MonadError для бесплатной Monad
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
Я хотел бы сделать DataStore
экземпляр MonadError
с сообщением об ошибке обрабатываются в (Free (Error str))
:
instance MonadError String DataStore where
throwError str = errorDS str
catchError (Free (ErrorDS str)) f = f str
catchError x _ = x
Но я бег в перекрывающихся экземплярах ошибки.
Какова правильность способа сделать монумент DataStore
и экземпляр MonadError
?
Вы можете обернуть его в «новый тип» и сами контролировать экземпляры. Я не думаю, что есть более чистый способ сделать это. Экземпляры для 'FreeT' предполагают, что вы не будете предоставлять ни один из классов mtl, предоставляемых другими трансформаторами. – Cirdec
Как это отличается от последней строки первого блока кода? –
@ JohnF.Miller В вашем примере «DataStore» - это просто псевдоним типа, а не «новый тип», который автоматически предоставляет вам все экземпляры Free'. Однако, если вы сделаете это «newtype», вы можете использовать «GeneralizedNewtypeDeriving», чтобы выбрать, какие экземпляры вы хотите наследовать, и вы можете определить свой собственный экземпляр «MonadError». –