4

テンプレートの目的で自由なモナドを定義するために、データ型のアラカルトアプローチを使用しようとしています。私はいくつかのコンビネータを書きましたが、行き詰まっています。私のプログラムは分岐し続けていますが、その理由がわかりません。

検討:

math :: Math :<: f => MathExpr a -> Free f ()
blank :: f :<: (Textual :+: Math) => Free f () -> Free (Blank k f) ()
equals :: Free (Math :+: (Blank L Math)) ()
       -> Free (Math :+: (Blank R Math)) ()
       -> Free Equation () 

コンポジション (空白 . 数学) のタイプは次のとおりです。

blank . math :: ( f :<: (Textual :+: Math)
                , Math :<: f
                ) => MathExpr a -> Free (Blank k f) ()

f は Textual と Math の結合よりも小さく、Math よりも大きくなければならないことに注意してください。したがって、f の唯一の可能性は数学です。(もしあったとしても、コンパイラーは私の側でさらに作業をしなければこれを推測できないことを認識しています)

評価しようとすると問題が発生します。

test :: Free Equation ()
test = (hoistFree (inj :: Blank 'L Math a -> (Math :+: Blank 'L Math) a)
     . blank
     . (math :: MathExpr x -> Free Math ())
     $ "hi"
     )
     `equals` (math $ "world")

これは明らかにループし、CPU を 100% に固定します。計算結果は次のように表示されます。

Free (Equation (Free (DirectSum {unDirectSum = Right

その時点で値は切り捨てられ、GHCi は終了します。したがって、equals の最初の引数が直和の後半部分にあることはわかるようですが、空白を計算することはできないようです。

私の関数はすべて合計であり、ここに底はありませんが、固定小数点コンビネータが得意ではありませんでした。何か案は?

編集: 無料のモナドを含むモジュールは次の場所にあります: http://lpaste.net/93471 モジュールの Data.Domain は次の場所にあります: http://lpaste.net/93472

4

1 に答える 1