2011-02-24 142 views
2

我是一种新的F#所以也许我的问题是愚蠢的。我在F#中编写了一个使用泛型类型的程序。编译器确定的类型不是我想要的方式,因为我在最深的函数调用中有一个错误,我已经将类型实例化为错误的类型。这显然导致了其他地方的类型不匹配,因为我曾经使用过这种类型。我不得不提到找到问题的根源,我试图明确强制执行更高级别的函数,以使用我希望用于泛型类型的类型。然而,类型不匹配显示在那些高级函数中,而不是低级函数是类型被实例化的。我认为这不是确定类型的非常方​​便的方式,因为通常程序员更容易确定更高级别函数的类型,并且如果类型已确定,则此显式类型分配应导致较低级别函数中的类型错误。根据我的经验,似乎编译器的自动类型确定会覆盖显式类型声明。我在这里理解错误吗?F#类型推断

类似下面的代码:

type test<'a,'b>={Func:'a->'b; Arg:'a} 

let C(a)= 
    a.Func(2)|>ignore 

let B(a)= 
    C(a) 

let A(a:test<int64,int64>)= 
    B(a) //<-----------------------the type mismatch is detected here 

在这样高水平的函数调用已经检测到的错误会使得它很难找到问题的根源,因为现在不仅我得找有关的虫子变量的值,还有类型确定的错误。

+3

“编译器的自动类型确定重写显式类型声明” - >否,它不... – 2011-02-24 02:08:19

+0

你可以发布你的代码吗?否则很难给你的具体问题提供建议...... – 2011-02-24 02:08:55

+0

@Mauricio Scheffer:现在我已经添加了代码示例。谢谢:) – amirmonshi 2011-02-24 02:26:27

回答

2

F#的类型推断是(相当)严格的从上到下,从左到右。看到这里的讨论:Why is F#'s type inference so fickle?

您可以通过重新安排这样的代码(只是为了演示)检查:

type test<'a,'b>={Func:'a->'b; Arg:'a} 

let rec B(a)= 
    C(a) 

and A(a:test<int64,int64>)= 
    B(a) 

and C(a)= 
    a.Func(2)|>ignore // type mismatch now here 

便利水平主要取决于具体的代码,以我的经验。但我不得不承认,我也有时会因类型不匹配错误消息而感到惊讶。这需要一段时间才能习惯。

+0

令人惊叹!谢谢,我不知道它是这样的。我相信如果我牢记这一点,它会为我节省很多。我没有看到在F#中引入更好类型的推理时存在什么障碍,它将优先考虑更明确的语义而不是声明的顺序。也许这是个人的事情,但我认为,例如在上面的例子中,测试应该是绝对的决定因素,而不是声明的顺序。除此之外,声明必须同时考虑类型和值实例化!这可能是非常严格的! – amirmonshi 2011-02-24 03:19:44