【问题标题】:Number of Parameters of a Haskell FunctionHaskell 函数的参数个数
【发布时间】:2017-11-01 16:51:19
【问题描述】:

当我尝试使用 ghc 编译它时,它抱怨函数定义左侧的参数数量不同。

module Example where

import Data.Maybe

from_maybe :: a -> Maybe a -> a
from_maybe a Nothing = a
from_maybe _ = Data.Maybe.fromJust

我想知道这是否是ghc 限制。我试着看看我是否 可以在 Haskell 2010 中找到有关参数数量的任何信息 报告,但我没有成功。

这是合法的 Haskell 还是不是?如果不是,这个参数计数在哪里 是否列出了限制?

【问题讨论】:

  • @amalloy 我不认为这是一个完全的骗局。
  • 那么,不要投票关闭它。这就是为什么结束一个问题需要 5 票。
  • @melpomene 我同意,linked question 要求提供决定背后的原因。这个要求参考规范。
  • @amalloy 请记住,您正在接近金牌 [haskell] 徽章,这将允许您自己关闭一个重复的问题。

标签: haskell


【解决方案1】:

这是不合法的。该限制在 Haskell 2010 Report:

4.4.3.1 函数绑定

[...]

请注意,定义函数的所有子句必须是连续的,并且每个子句中的模式数量必须相同。

【讨论】:

  • 非常感谢。这就是我一直在寻找的。​​span>
【解决方案2】:

melpomene 中的answer 是语法规则的总和。在这个答案中,我想尝试描述为什么会这样。

从程序员的角度来看,问题中的语法似乎很合理。有第一个特定情况,它由第二个参数中的值标记。然后有一个通用的解决方案,它可以简化为现有的功能。任何一种模式本身都是有效的,那么为什么它们不能共存呢?

所有模式必须捕获完全相同的参数的语法规则是haskell作为一种惰性语言的必然结果。懒惰意味着参数的值在需要时才被评估。

让我们看看当我们对函数进行 curry 时会发生什么,即为它提供的参数数量少于声明中的参数数量。当这种情况发生时,haskell 会生成一个匿名函数*,它将完成该函数并将第一个参数存储在该函数的范围内而不评估它们

最后一部分很重要。对于具有不同数量参数的函数,有必要评估其中一些以选择要匹配的模式,然后不评估它们。

换句话说,编译器需要准确地知道它需要多少个参数,然后才能评估它们以在模式中进行选择。因此,虽然我们似乎不需要在其中添加额外的 _,但编译器需要它。

顺便说一句,参数出现的顺序会对函数实现和使用的难易程度产生很大影响。请参阅我的问题Ordering of parameters to make use of currying 的答案以获取建议。如果在示例函数中顺序颠倒,则可以仅使用一个命名点来实现。

from_maybe :: Maybe a -> a -> a
from_maybe Nothing = id
from_maybe (Just x) = const x

*:像 GHC 这样的实现在这种情况下实际所做的工作需要优化,可能无法完全按照这种方式工作,但最终结果必须与它所做的相同。

【讨论】:

  • "编译器需要确切地知道它需要多少个参数才能评估它们以在模式中进行选择" - 不,它不需要。你在想什么问题?
  • 案例:Agda 现在支持具有不同数量模式的子句,当模式可能导致 RHS 成为函数类型并且您希望在该额外参数上进行模式匹配时,这非常方便.
  • Agda 的语义不是惰性的,所以不会出现求值顺序的问题。 Agda 是一种完整的语言,即其中的每个程序都必须终止,并且必须匹配所有可能的模式。如果没有这个特性,语言背后的逻辑就会变得不一致,并且可以证明任意陈述。 Haskell 不是全面的,因此评估顺序很重要,功能缩减必须一致。我坚持我的答案。
  • 我不明白这有什么不同。 Agda 对声明子句的顺序也很敏感。并且在模式中过于严格会阻止一些否则会发生的减少。这种可变数量的参数可以很好地适应 Haskell 的扩展。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-11
  • 1970-01-01
相关资源
最近更新 更多