键入函数的推断作为参数

时间:2015-08-22 12:27:56

标签: f#

我想写一个函数,它接受几个tupples作为参数并选择他们的元素并传递给另一个函数,其中i作为另一个参数给出。我试过这样的事:

let function (tup1:'A*'A) (tup2:'B*'B) i =
    otherFunction (i tup1) (i tup2)
function Tup1 Tup2 fst

我收到了错误消息,因为i预计会'A*'A ->'A而不是'B*'B->'B。 是否可以使此代码工作?

提前致谢。

2 个答案:

答案 0 :(得分:4)

你基本上想要传递∀'a.'a*'a->'a类型的参数,但是在F#(和其他ML)中,只支持rank-1 polymorphism,所以你不能直接这样做。解决方法是使用通用方法定义一个新类型来模拟更高级别的多态:

type Untupler =
    abstract Apply : 'a*'a -> 'a

let myFunction tup1 tup2 (i:Untupler) =
    otherFunction (i.Apply tup1) (i.Apply tup2)

myFunction Tup1 Tup2 { new Untupler with member __.Apply (x,y) = x }

答案 1 :(得分:3)

当您将i函数与tup1一起使用时,它被推断为'A * 'A -> 'A类型。这意味着当您将其与tup2一起使用时,唯一可行的方法是tup2 还是'A * 'A

函数i无法在同一函数中更改类型。如果有办法做你想做的事,我不知道,但你可以回避这样的问题:

let myFunction x y =
    otherFunction x y

这样称呼:

myFunction (fst tup1) (fst tup2)

这给调用者带来了更多的责任,但优点是它可能:)