我想写一个函数,它接受几个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
。
是否可以使此代码工作?
提前致谢。
答案 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)
这给调用者带来了更多的责任,但优点是它可能:)