2013-10-28 58 views
6

GHC警告我没有顶层的功能签名。我不明白为什么我需要他们。与提供它们的问题是,他们是相当复杂的,像这样的(自动生成):为什么我的顶级函数需要在Haskell中签名?

applyValue :: forall t t1 t2 t3 t4. 
       (t2 -> t) 
       -> (t2 -> t3 -> t4 -> t1) -> t2 -> t3 -> t4 -> (t -> Bool) -> [t1] 

那么,为什么我懒得将它们添加?

函数本身:

applyValue getValueAt stitchAndMove at fabric mark matchAt = 
    if matchAt (getValueAt at) 
    then [stitchAndMove at fabric mark] 
    else [] 
+0

您是否启用了任何扩展功能? –

+0

我们可以看到一些代码吗? – jozefg

+6

如果发生这种情况是因为您使用'-Wall'编译,则可以使用'-fno-warn-missing-signature'。不排除他们是好的做法 - 请参阅Daniel Wagner的回答,原因是为什么。 –

回答

22
  • 如机器可检查文档的形式。如果你认为这种类型是正确的类型,那么在那里要求编译器仔细检查你在以后不可避免的重构会话期间是否没有使用自己的接口。
  • 作为人类可读的文档。虽然正如你所观察到的,但当你注意到你正在编写一个糟糕的机器生成类型的时候,现在可能是时候考虑一​​下你需要什么(类型)抽象来让它变得易读。
  • 黑线鳕。 Haddock的注释会附加到类型签名上,而不是绑定,所以如果你遗漏了类型签名,那么你仔细手写的文档将被默默地忽略。
  • 改善错误信息和ghci查询结果:尽管类型变量的实际名称并不重要,但当用户提供名称时,GHC会尽力保留名称。类似于(node -> Bool) -> (edge -> Bool) -> (graph -> Bool)可以比(t1 -> Bool) -> (t2 -> Bool) -> (t3 -> Bool)更具可读性,即使它们是相同的。
+1

您的观点很有道理,但我还有一个很快的问题,是否有重用签名块的方法,例如我有一个长而复杂的函数f1的签名,现在f2需要f1,所以它就是关于f2 + f1的所有内容是。我想知道是否可以通过将签名f1分配给某些名称(类型?)来保存一些工作,并在定义f2的签名时通过该名称引用它。谢谢 –

+6

@AlekseyBykov是的,这是'类型别名做的。你可以在报告或你最喜欢的教程中阅读它们。 –

+1

即使您不关心文档或错误消息,签名有时也是必需的。有时候,你想要什么样的类的实例是模糊的,因此你需要明确地约束它以便编译。 – newacct

相关问题