現在、モナドトランスフォーマーに少し苦労しています。トランスフォーマーを利用するいくつかの異なる非決定論的関係を定義しています。残念ながら、ある効果的なモデルから別のモデルにきれいに変換する方法を理解するのに苦労しています。
これらの関係が「foo」と「bar」であるとします。「foo」が As と B を C に関連付けるとします。「バー」が B と C を D に関連付けるとします。「foo」に関して「bar」を定義します。さらに興味深いことに、これらの関係の計算はさまざまな方法で失敗します。(bar リレーションは foo リレーションに依存するため、その失敗ケースはスーパーセットです。) したがって、次の型定義を与えます。
data FooFailure = FooFailure String
data BarFailure = BarSpecificFailure | BarFooFailure FooFailure
type FooM = ListT (EitherT FooFailure (Reader Context))
type BarM = ListT (EitherT BarFailure (Reader Context))
次に、次の関数シグネチャを使用してリレーションを記述できることを期待します。
foo :: A -> B -> FooM C
bar :: B -> C -> BarM D
私の問題は、「バー」の定義を書くときに、「foo」リレーションからエラーを受け取り、それらを「バー」スペースで適切に表現できる必要があることです。したがって、次の形式の関数で問題ありません
convert :: (e -> e') -> ListT (EitherT e (Reader Context) a
-> ListT (EitherT e' (Reader Context) a
ListT を実行し、EitherT にマッピングし、ListT を再構築することで、その小さな獣を書くことさえできます (たまたま m [a] が ListT ma に変換される可能性があるためです)。しかし、これは... 面倒です。
トランスフォーマーを実行して、その下でいくつかのことを行い、一般的に「元に戻す」ことができないのには十分な理由があります。私が実行したトランスフォーマーには効果がある可能性があり、魔法のようにそれらを元に戻すことはできません. convert
しかし、上記の関数を記述する必要がないように、関数をトランスフォーマースタックに持ち上げて何らかの作業を行う方法はありますか?