1

我遇到了一些我不明白的 Array.map2。

考虑这段代码:

type r1 = {
    v1 : int
    X : int
}

type r2 = {
    v1 : int 
    Y : int
}

let a1 = [|{v1=1;   X=1};   {v1=2;   X=2}|]   // val a1 : r1 [] ...
let a2 = [|{v1=100; Y=100}; {v1=200; Y=200}|] // val a2 : r2 [] ...

Array.map2 (fun x1 x2 -> (x1.X, x2.Y)) a1 a2   // works as expected
Array.map2 (fun x1 x2 -> (x1.v1, x2.v1)) a1 a2  // error FS0001: Type mismatch. Expecting a r2 [] but given a r1 [] 

两条记录都有一个字段v1。在最后一行中,我尝试v1从不同的记录类型r1和中获取 的值的元组r2。当我尝试在不同记录上选择具有相同名称的字段时,似乎会引发错误。

不知何故,它得出了x1必须是 type的结论r2,为什么第二行不从两个参数a1和推断类型a2

编辑

这修复了它,但我希望从参数中获得正确的类型。

Array.map2 (fun (x1:r1) x2 -> (x1.v1, x2.v1)) a1 a2  // works
4

1 回答 1

5

类型检查器从左到右工作,因此在第二个示例中没有足够的信息来解决冲突。您的第一个示例很好,因为.X和分别是和.Y上的唯一字段。r1r2

也就是说,在这种情况下,您可以在访问记录字段之前使用管道为类型检查器提供类型a1和可用的类型:a2

(a1, a2) ||> Array.map2 (fun x1 x2 -> (x1.v1, x2.v1))

通常,您应该使用包含唯一字段的记录模式来识别正确的类型:

Array.map2 (fun {v1 = a; X = _} {v1 = b; Y = _} -> (a, b)) a1 a2

或提供完全限定的字段名称:

Array.map2 (fun {r1.v1 = a} {r2.v1 = b} -> (a, b)) a1 a2
于 2012-10-28T22:09:44.557 回答