如何获得具有可变数量参数的int元组的乘积?

时间:2016-12-29 07:57:07

标签: generics f# constraints

type TotalSizeToken = TotalSizeToken with
    static member TotalSize(_: TotalSizeToken, (a,b,c,d,e)): int = a*b*c*d*e
    static member TotalSize(_: TotalSizeToken, (a,b,c,d)): int = a*b*c*d
    static member TotalSize(_: TotalSizeToken, (a,b,c)): int = a*b*c
    static member TotalSize(_: TotalSizeToken, (a,b)): int = a*b
    static member TotalSize(_: TotalSizeToken, x: int): int = x

let inline size_to_total_size x = 
    ((^s) : (static member TotalSize: TotalSizeToken * ^s -> int) TotalSizeToken, x)

let t = size_to_total_size (1,5) // Error: Expecting a type supporting the operator TotalSize, but given a tuple type.

我没想到x中的size_to_total_size参数需要TotalSize成员。这感觉就像编译错误。

我不知道如何让它发挥作用。有什么想法吗?

2 个答案:

答案 0 :(得分:8)

你错过了另一个'帽子'类型:

let inline size_to_total_size x = 
    let call (t:^T) = ((^s or ^T) : (static member TotalSize: TotalSizeToken * ^s -> int) t, x)
    call TotalSizeToken

必须有两个,传递的参数和表示包含重载的类的参数。

否则它将永远不会查看类,只在元组中,并且元组类型中没有这样的方法。

答案 1 :(得分:1)

type TotalSizeToken<'u> = TotalSizeToken of 'u with
    static member TotalSize(x: TotalSizeToken<int*int*int*int*int>): int = 
        match x with TotalSizeToken (a,b,c,d,e) -> a*b*c*d*e
    static member TotalSize(x: TotalSizeToken<int*int*int*int>): int = 
        match x with TotalSizeToken (a,b,c,d) -> a*b*c*d
    static member TotalSize(x: TotalSizeToken<int*int*int>): int = 
        match x with TotalSizeToken (a,b,c) -> a*b*c
    static member TotalSize(x: TotalSizeToken<int*int>): int = 
        match x with TotalSizeToken (a,b) -> a*b
    static member TotalSize(x: TotalSizeToken<int>): int = 
        match x with TotalSizeToken x -> x

let inline size_to_total_size x = 
    ((^s) : (static member TotalSize: ^s -> int) x)

let t = size_to_total_size (TotalSizeToken(1,5))

这种替代形式有效。还有一些额外的拳击,但从好的方面来说,我不需要到处传递lambdas。奇怪的是,如果size_to_total_size的编写方式与let inline size_to_total_size x = ((^s) : (static member TotalSize: TotalSizeToken< ^s> -> int) x)相同,则无效。