2012-03-30 6 views
5

Desidero trasformare il mio trasformatore monad in istanza di MonadError se la monade trasformata è un'istanza. Fondamentalmente io voglio che il mio trasformatore a comportarsi come i trasformatori incorporati fanno, ad esempio, v'è un esempio MonadError per StateT:Creazione di un trasformatore monodin personalizzato un'istanza di MonadError

MonadError e m => MonadError e (StateT s m) 

Ho provato a fare questo:

instance MonadError e m => MonadError e (MyMonadT m) 

Ma GHC iniziato a lamentarsi indecidibile istanze, apparentemente la libreria MTL abilita solo istanze indecidibili, ma esiste un modo per evitarlo? O è OK in questo caso e non causerà alcun problema?

risposta

8

Questo è fondamentalmente buono. UndecidableInstances non è poi così spaventoso; Tutto ciò significa che il compilatore potrebbe, invece di trovare un'istanza, entrare in un ciclo infinito. Il suona come piuttosto male, finché non ti rendi conto che GHC ha effettivamente un limite al numero di passi necessari per trovare un'istanza; nulla andrà storto a meno che non si scriva una brutta istanza, e i messaggi di errore che si otterranno generalmente renderanno molto evidente ciò che è andato storto. Certamente è molto meno spaventoso di cose come OverlappingInstances (o peggio, IncoherentInstances).

La ragione per cui si lamenta è che ha una dipendenza funzionale da m a e. Ciò significa che la scelta di m determina cosa deve essere e; Ad esempio, ogni m è associato a un solo e. Il controllo per questo (la condizione di copertura) è prudente, quindi è facile imbattersi in problemi come questo, dove si tenta di "recurse down level" per specificare e.

Elencherà tutte le istanze esaminate per cercare e trovare quello che sta cercando, quindi vedrete un mucchio di linee ripetute. Ma di solito non ti troverai nemmeno nei guai come questo in primo luogo.