私は小さな言語のためにF#でDSLを実装しようとしています。残念なことにコンパイラは、(ファントム型を介して)追加の型情報を保持するようにノードを制約しようとすると、自分のトラックで私を死に至らせてしまいます。コードのこのコンストラクトは、コードの汎用性が低くなります...ファントムタイプに適用すると
次の行は、問題を示しています
type Expr<'a> =
| Int of int
| Eq of Expr<int> * Expr<int>
| Not of Expr<bool>
let rec to_string (expr: Expr<'a>) =
match expr with
| Int(n) -> string n
| Eq(x, y) -> sprintf "%s == %s" (to_string x) (to_string y)
| Not(b) -> sprintf "!%s" (to_string b)
コンパイラによる構造to_string x
次の警告を発行:次の行、構造上、ということに続き
construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type 'int'.
をto_string b
このエラーを発行します:
Type mismatch. Expecting a
Expr<int>
but given aExpr<bool>
The typeint
does not match the typebool
私はこの振る舞いを回避する方法を見つけることができないと思うし、実際に私はこのコードが私が予想していたより一般的でない原因を見つけることができません。可能であれば、私はファントムタイプを完全に放棄しないソリューションを好むだろう。
私は基本的に何か間違っていますか?これはコンパイラのバグでしょうか?