2015-10-02 18 views
7

Küçük bir dil için F # uygulamasında bir DSL uygulamasına çalışıyorum. Maalesef düğümler ek tip bilgileri (hayalet tipler aracılığıyla) tutmak için düğümleri kısıtlamaya çalıştığımda parçalarımda beni ölüler. to_string x konular aşağıdaki uyarı konstrukt derleyici göreBu yapı, kodun daha az genel olmasına neden oluyor ... phantom türüne uygulandığında,

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) 

:

aşağıdaki kod satırlarını

sorunun açıklanmasına o takiben

construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type 'int'.

, sonraki satırda, yapı üzerinde to_string b Bu hatayı verir:

Bu davranışı atlatmanın hiçbir yolunu bulamıyorum ve aslında bu kodun beklediğimden daha az jenerik olmasının sebebini bulamıyorum. Mümkünse fantom türlerini tamamen terk etmeyen bir çözümü tercih ederim.

Temel olarak yanlış bir şey yapıyorum? Bu bir derleyici hatası olabilir mi?

cevap

9

Sen jenerik to_string fonksiyonunu yapmak gerekir:

let rec to_string<'a> (expr:Expr<'a>) : string = 
    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) 

Eğer fonksiyonu

Not (Eq (Int 1, Int 2)) 
|> to_string 
çağırdığınızda tür parametresi anlaşılmaktadır edilecektir
İlgili konular