2017-10-04 9 views
5

この場合、インライン処理が機能しないのはなぜですか?タプル用のインライン展開はなぜ機能しないのですか?

type TupleBuilder() = 
    static member inline Cons(a,(b,c)) = (a, b, c) 
    static member inline Cons(a,(b,c,d)) = (a, b, c, d) 
    static member inline Cons(a,(b,c,d,e)) = (a, b, c, d, e) 

let inline cons h t = TupleBuilder.Cons(h,t) 

TupleBuilder.Consへの呼び出しは私に

A unique overload for method 'Cons' could not be determined based on type 
information prior to this program point. A type annotation may be needed. 
Candidates: 
static member TupleBuilder.Cons : a:'a0 * ('a1 * 'a2 * 'a3 * 'a4) -> 'a0 * 'a1 * 'a2 * 'a3 * 'a4, 
static member TupleBuilder.Cons : a:'a0 * ('a1 * 'a2 * 'a3) -> 'a0 * 'a1 * 'a2 * 'a3, 
static member TupleBuilder.Cons : a:'a0 * ('a1 * 'a2) -> 'a0 * 'a1 * 'a2 
+0

コンパイラは、 'cons'関数で' t'の要素数を知っていますか?使用法を見ることなく、 't'が2タプル、3タプル、または4タプルであるかどうかはわかりません。 – rmunn

+0

通常、 'inlining'はコールサイトにその決定を遅らせるのに役立ちます。しかし、ここではありません。だから私は不思議です – robkuz

答えて

7

インライン化だけでは呼び出しサイトへの過負荷の決定を遅らせることはありません。次のコンパイラエラーが発生します。 オーバーロードコール時にtype A or type Bを追加する必要があります。

あなたは、このケースでは二項演算子を使って、簡単にそれを行うことができます。

タプルでより多くのインライン楽しみのために
type TupleBuilder() = 
    static member inline ($) (_:TupleBuilder, (b,c))  = fun a -> (a, b, c) 
    static member inline ($) (_:TupleBuilder, (b,c,d)) = fun a -> (a, b, c, d) 
    static member inline ($) (_:TupleBuilder, (b,c,d,e)) = fun a -> (a, b, c, d, e) 

let inline cons h t = (TupleBuilder() $ t) h 


// val inline cons : h:'a -> t: ^b -> 'c 
    when (TupleBuilder or ^b) : (static member ($) : TupleBuilder * ^b -> 'a -> 'c) 

は、this old blog postを見ています。

関連する問題