【问题标题】:Function pattern matching in HaskellHaskell 中的函数模式匹配
【发布时间】:2016-04-26 03:22:54
【问题描述】:

我正在尝试在 Learn You a Haskell 的指导下学习 Haskell,但以下内容让我感到困惑。

lucky :: (Integral a) => a -> String
lucky 7 = "LUCKY NUMBER SEVEN!"  
lucky x = "Sorry, you're out of luck, pal!"

如您所见,其中有一行说明了函数的确切类型。但这有必要吗?不能从该行下面的模式推导出参数和返回值的类型吗?

【问题讨论】:

标签: haskell


【解决方案1】:

你是对的,它们绝对没有必要。然而,声明函数的类型是一种非常普遍的做法,至少有两个原因:

  • 告诉编译器您的实际意思。万一你写错了函数,编译器不会推断出错误的类型,而是警告你你的错误
  • 告诉阅读您的代码的人。他们在理解代码时无论如何都必须找出函数的类型,所以你不妨让他们更容易。明确指定类型会使代码更具可读性。

这就是为什么尽管它们是可选的,但顶级函数的类型几乎总是在 Haskell 代码中说明。


为了完成 Zeta 所说的,在这种情况下没有必要。但是,在某些情况下,当代码太模糊而无法推断时,需要指定函数的类型。

【讨论】:

  • 该行是否生成实际代码(例如一些运行时类型检查?我对 Haskell 完全陌生..)
  • 您应该将其作为对编译器的提示阅读(根据这些提示可能会或可能不会更改生成的代码) - 如果您不给出它,编译器将尝试推断它跨度>
  • “你说得对,它们绝对没有必要。”这个的情况下。如果您留下类型签名并吐出几页歧义错误,GHC 会在几种情况下对您大喊大叫。
  • @JohnsonSteward:不! Haskell 是静态类型的,所有类型都在编译时解析。无论您是告诉编译器类型是什么(使用类似的类型签名),还是让编译器自己弄清楚(通过类型推断),生成的代码都是相同的。 (一个例外:如果你给代码一个更具体的类型,那么编译器可能会产生不同的输出。)
  • 进一步阅读,发现了这一点:zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]。似乎这对于编译器来说不容易推导出来......
【解决方案2】:

出于文档目的,并且因为对于某些类型扩展,自动推理失败。阅读here

【讨论】:

  • 1.链接坏了。 2. 目前,您的答案几乎是仅链接的答案。在答案本身中添加更多信息。
  • @Zeta 2 同意,但 1 个链接没有损坏。
  • @JohnsonSteward:前五分钟忍者编辑。
  • 是的,我在第一条评论后做了一个忍者编辑。顺便说一句,我认为该链接对 haskell 初学者有很好的解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-04
相关资源
最近更新 更多