2017-10-04 55 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

通常情況下,「內聯」有助於將決定延遲到呼叫站點。但不在這裏。所以我想知道 – 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