2016-09-26 31 views
3

良いと期待どおり型推論の回避策

let oi = checkOne (One 1) 
let os = checkOne (One "1") 
let tis = checkTwo (Two (1, "1")) 
let tsi = checkTwo (Two ("1", 1)) 

私は好きなようにタイプを切り替えることができます。
は今、私は

let makeUC() = (checkOne, checkTwo) 

1つの作成機能にそれらの二つの機能を組み合わせて、その後にのみ、それは私に実際に今

Value restriction. The value 'o' has been inferred to have generic type 
    val o : (SomeDU2<'_a,'_b> -> bool)  
Either make the arguments to 'o' explicit or, if you do not intend for it to be generic, add a type annotation. 
val o : (SomeDU2<obj,obj> -> bool) 

このエラーメッセージを表示します。この

let (o,t) = makeUC() 

のようにインスタンス化したいが私はそれを望んでいない - 私はそれを必要としない。 おそらく、F#で上位の種別の型が見つからない場合があります これには方法がありますか?以下@johnsコメントどおり

編集

実際に私の質問波平のcomplety。 はもちろん、私はその後、後方推論otはタイプSomeDU2<int,int> -> boolであるようになり、次の

let ro1 = o ((One 1) : SomeDU2<int,int>) 
let rt1 = t (Two (1,2)) 

行うことができます(私は非常に奇妙なあなたを推論後方これを見つけます)。問題は、oがもうこれ以上許されないということです。

let ro2 = o ((One "1") : SomeDU2<string,int>) 

だから私はSomeDU2の一般的なパラメータの組み合わせ毎に特定oのインスタンスをインスタンス化する必要があると思います。

+3

つのオプション:一般的な方法で、公称タイプのエラーメッセージが言う何をするか、メッセージo' '使用した場合のいずれかは、おそらく離れて行きます –

+0

@JohnPalmerが原因コメント – robkuz

+1

にいくつかのより多くの情報を追加しましたどのように計画していますか?関数のタプルを使うのはどうですか?厄介なようだ。あなたは何を達成しようとしていますか? – asibahi

答えて

3

あなたもタプルなし値制限に実行します:

let o = (fun() -> checkOne)() 

あなたが任意の型の値に適用される関数を呼び出すの結果が必要な場合は、その一つの解は、のインスタンスを作成することです

type DU2Checker = 
    abstract Check : SomeDU2<'a,'b> -> bool 

let checkOne = { 
    new DU2Checker with 
    member this.Check(x) = 
     match x with 
     | One _ -> true 
     | _ -> false } 

let checkTwo = { 
    new DU2Checker with 
    member this.Check(x) = 
     match x with 
     | Two _ -> true 
     | _ -> false } 

let makeUC() = checkOne, checkTwo 

let o,t = makeUC() 

let false = o.Check(Two(3,4))