Al momento sto avendo un po 'di difficoltà con i trasformatori monad. Sto definendo alcune diverse relazioni non deterministiche che fanno uso di trasformatori. Sfortunatamente, ho difficoltà a capire come tradurre in modo pulito da un modello efficace a un altro.Transformation under Transformers
Supponiamo che queste relazioni siano "foo" e "bar". Supponiamo che "foo" si riferisca a As e Bs a Cs; supponiamo che "bar" contenga Bs e Cs a Ds. Definiremo "bar" in termini di "foo". Per rendere le cose più interessanti, il calcolo di queste relazioni fallirà in modi diversi. (Poiché la relazione bar dipende dalla relazione foo, i suoi casi di fallimento sono un superset.) Ho quindi dare le seguenti definizioni del tipo:
data FooFailure = FooFailure String
data BarFailure = BarSpecificFailure | BarFooFailure FooFailure
type FooM = ListT (EitherT FooFailure (Reader Context))
type BarM = ListT (EitherT BarFailure (Reader Context))
Vorrei quindi aspetto di essere in grado di scrivere i rapporti con i seguenti identificativi di funzione :
foo :: A -> B -> FooM C
bar :: B -> C -> BarM D
mio problema è che, quando si scrive la definizione di "bar", ho bisogno di essere in grado di ricevere gli errori dalla relazione "pippo" e correttamente li rappresentano nello spazio "bar". Quindi sarei fine con una funzione della forma
convert :: (e -> e') -> ListT (EitherT e (Reader Context) a
-> ListT (EitherT e' (Reader Context) a
Posso anche scrivere che bestiola eseguendo il ListT, mappatura su EitherT, e poi rimontare il ListT (perché capita che m [a] può essere convertiti in ListT ma). Ma questo sembra ... disordinato.
C'è una buona ragione per cui non posso semplicemente eseguire un trasformatore, fare alcune cose sotto e genericamente "rimetterlo"; il trasformatore che ho eseguito potrebbe avere effetti e non riesco magistralmente a annullarli. Ma c'è un modo in cui posso sollevare una funzione abbastanza in una pila di trasformatori per fare un po 'di lavoro per me quindi non devo scrivere la funzione convert
mostrata sopra?
Sì, stavo boicottando ListT. Usa 'pipe' per un ListT corretto. Inoltre, puoi usare 'fmapLT' dal pacchetto errori per modificare il valore di sinistra. –
Stavo cercando 'fmapLT' ...! Ma avrei giurato che era in "entrambi" e non l'ho fatto. –
Eccellente; grazie ad entrambi. Questo è esattamente ciò di cui mi stavo chiedendo. :) – tvynr