このブログ投稿をフォローしています: http://semantic-domain.blogspot.com/2012/12/total-functional-programming-in-partial.html
これは、 System T (単純な完全関数型言語)用の小さな OCaml コンパイラ プログラムを示しています。
パイプライン全体が (Camlp4 メタプログラミングを介して) OCaml 構文を使用して、それらを OCaml AST に変換し、SystemT ラムダ計算 (参照: module Term
) に変換し、最後に SystemT Combinator 計算 (参照:
module Goedel
) に変換します。最後のステップも OCaml メタプログラミングAst.expr
タイプでラップされます。
Template Haskell を使用せずに Haskell に変換しようとしています。
SystemT Combinator フォームについては、次のように記述しました。
{-# LANGUAGE GADTs #-}
data TNat = Zero | Succ TNat
data THom a b where
Id :: THom a a
Unit :: THom a ()
ZeroH :: THom () TNat
SuccH :: THom TNat TNat
Compose :: THom a b -> THom b c -> THom a c
Pair :: THom a b -> THom a c -> THom a (b, c)
Fst :: THom (a, b) a
Snd :: THom (a, b) b
Curry :: THom (a, b) c -> THom a (b -> c)
Eval :: THom ((a -> b), a) b -- (A = B) * A -> B
Iter :: THom a b -> THom (a, b) b -> THom (a, TNat) b
Compose
は順合成であり、 とは異なることに注意してください(.)
。
SystemT ラムダ計算から SystemT コンビネータ計算Elaborate.synth
への変換中に、関数は SystemT ラムダ計算変数を一連の合成射影式 (De Brujin Indices に関連) に変換しようとします。これは、コンビネータ計算に変数/変数名がないためです。Elaborate.lookup
これは、 関数を使用する で行われQuote.find
ます。
問題は、コンビネータ計算を GADT としてエンコードすることTHom a b
です。関数の翻訳Quote.find
:
let rec find x = function
| [] -> raise Not_found
| (x', t) :: ctx' when x = x' -> <:expr< Goedel.snd >>
| (x', t) :: ctx' -> <:expr< Goedel.compose Goedel.fst $find x ctx'$ >>
Haskellに:
find :: TVar -> Context -> _
find tvar [] = error "Not Found"
find tvar ((tvar', ttype):ctx)
| tvar == tvar' = Snd
| otherwise = Compose Fst (find tvar ctx)
無限型エラーになります。
• Occurs check: cannot construct the infinite type: a ~ (a, c)
Expected type: THom (a, c) c
Actual type: THom ((a, c), c) c
この問題は、GADTCompose
で andFst
とSnd
fromを使用するとTHom a b
、型シグネチャが無限に変化する可能性があるという事実から生じます。
Ast.expr
この記事では、 OCamlを使用して基になる式をラップしているように見えるため、この問題はありません。
Haskellで解決する方法がわかりません。次のような存在量化型を使用する必要がありますか
data TExpr = forall a b. TExpr (THom a b)
Fix
または、無限型の問題を適応させるためのある種の型レベル。find
ただし、これがor関数をどのように変更するかはわかりませんlookup
。