为什么我的顶级函数需要在Haskell中签名?

Tri*_*Gao 6 haskell

GHC警告我在顶层没有功能签名.我不明白为什么我会需要它们.提供它们的问题是它们非常复杂,就像这个(自动生成):

applyValue :: forall t t1 t2 t3 t4.
                (t2 -> t)
                -> (t2 -> t3 -> t4 -> t1) -> t2 -> t3 -> t4 -> (t -> Bool) -> [t1]
Run Code Online (Sandbox Code Playgroud)

那么我为什么还要加入呢?

功能本身:

applyValue getValueAt stitchAndMove at fabric mark matchAt =
   if matchAt (getValueAt at)
   then [stitchAndMove at fabric mark]
   else []
Run Code Online (Sandbox Code Playgroud)

Dan*_*ner 23

  • 作为机器可检查文档的一种形式.如果您认为该类型是正确的类型,那么将它放在那里要求编译器仔细检查您在以后不可避免的重构会话期间是否没有使用自己的接口.
  • 作为人类可读的文档.虽然正如你所观察到的那样,当你注意到你正在编写一个糟糕的机器生成类型时,可能是时候考虑一​​下你需要什么(类型级)抽象来使它具有人类可读性.
  • 对于黑线鳕.Haddock注释附加到类型签名,而不是绑定,因此如果省略类型签名,您将仔细忽略您的精心手写的文档.
  • 要改进错误消息和ghci查询结果:虽然类型变量的实际名称无关紧要,但GHC会在用户提供名称时努力保留名称.类似的东西(node -> Bool) -> (edge -> Bool) -> (graph -> Bool)可以比(t1 -> Bool) -> (t2 -> Bool) -> (t3 -> Bool)它们更具可读性,即使它们是等价的.

  • @AlekseyBykov是的,这就是`type`别名.您可以在报告或您最喜欢的教程中阅读它们. (6认同)
  • 即使您不关心文档或错误消息,签名有时也是必要的。有时,您想要的类型类的实例是不明确的,因此您需要显式约束它才能编译。 (2认同)