一般に、SOについて質問するときは、試みを共有することをお勧めします。人々は一般的にあなたにあなたの問題の完全な解決策を与えることはありません-あなたが特定の質問をしたり問題に取り組む方法を示唆したときに答えるだけです。
それで、私は一般的なアプローチについていくつかのヒントを共有しますが、それは完全な解決策ではありません。まず、ASTを何らかの方法で表現する必要があります。F#では、識別された共用体を使用してこれを行うことができます。以下は、変数、値、および関数アプリケーションをサポートします。
type Expr =
| Function of string * Expr list
| Variable of string
| Value of int
統合は、型を統合する式のリストを取得し、変数への(Expr * Expr) list
割り当てを返す(Expr
変数名への式の割り当てstring
)関数です。
let rec unify exprs =
match exprs with
// Unify two variables - if they are equal, we continue unifying
// the rest of the constraints, otherwise the algorithm fails
| (Variable s1, Variable s2)::remaining ->
if s1 = s2 then unify remaining
else failwith "cannot unify variables"
// Unify variable with some other expression - unify the remaining
// constraints and add new assignment to the result
| (Variable s, expr)::remaining
| (expr, Variable s)::remaining ->
let rest = unify remaining
// (s, expr) is a tuple meaning that we assign 'expr' to variable 's'
(s, expr)::rest
// TODO: Handle remaining cases here!
| _ -> failwith "cannot unify..."
追加する必要があるケースがいくつかあります。最も重要なことは、と統合Function
するFunction
ということは、関数名が同じであることを確認し(そうでない場合は失敗する)、すべての引数式を新しい制約としてremaining
リストに追加する必要があることを意味します...