【问题标题】:argument naming rule in haskellhaskell中的参数命名规则
【发布时间】:2014-01-05 12:54:40
【问题描述】:

为什么不允许同名的参数在同一个方程中出现多次? 例子:

f a a = show a

d && d = d
_ && _ = False

从技术上讲,形式参数(报告称这些变量)也是模式——只是它们永远不会匹配一个值。作为成功匹配的“副作用”,形式参数绑定到它正在匹配的值。出于这个原因,任何一个方程中的模式都不允许出现多次相同的形式参数(一种称为线性的属性 §3.17、§3.3、§4.4.3)。

【问题讨论】:

  • 它的语义是什么?例如,如果您像f 1 2 一样调用f,结果应该是什么?
  • @PedroRodrigues-我自己也想要这个很多次了!它将与“f x y | x == y = ....”相同(如果 x /= y,它将回退到下一个模式)。熟悉语言规范流程的人可以告诉我们为什么不允许这样做!是有原因的,还是只是从未考虑过?
  • WinGHCi: Prelude> let _ && _ = False => (0.00 secs, 0 bytes) => Prelude> 5 && 6 => False
  • @jamshidh 对于没有Eq 实例的类型意味着什么?甚至对于两个不同类型的参数?
  • @fjh- 如果xy 没有Eq 实例,或者它们是不同的类型,则它的含义与f x y | x == y = .... 的含义完全相同-编译器错误。

标签: variables haskell arguments naming-conventions


【解决方案1】:

你不能定义

d && d = d
_ && _ = False

因为您正在尝试对变量使用模式匹配。

模式匹配只适用于数据构造函数,所以

True && True = True

没问题,但是

d && d = d

的意思是“取第一个参数(我们称之为d)和第二个参数(我们称之为d)和......”但是编译器打断你说
“不,等等,不要都叫他们d,我不知道你说的是哪一个!”你说
“但我只希望你在它们相同的情况下这样做”,编译器说
“这不是名称的用途 - 使用 a == b 进行测试。请不要在不使用 == 的情况下检查相等性,除非您通过将数据定义为 ==,否则我不知道您所说的相等性Eq 类型类的实例,在这种情况下,我希望你在类型签名中警告我,以便我可以得到正确的 == 定义。”

当你说f a a = show a,然后向show 3 4提问时,编译器会说“你想让我显示哪个?”

【讨论】:

    【解决方案2】:

    根据this mailing list post 的说法,这在 Miranda 中是允许的,并且是常见的错误来源:人们会意外地以相同的方式命名两个变量,并且很难发现这样一个微妙的错误。所以 Haskell 不允许它支持显式添加警卫。

    我个人认为这对你的代码的可怜的读者来说也更温和,由于这条规则,他们不需要记住模式匹配站点范围内的所有不同变量来查看是否模式实际上是否匹配所有内容。

    【讨论】:

    • 好答案-我还想添加一些东西.... Perl正则表达式基本上允许与反向引用类似的东西(即,反斜杠后跟RE中的单个数字,例如/(\w+) \1/,匹配由空格分隔的相同单词)。如果 Haskell 本身有一个反向引用字符,可能会更不容易出错,比如 f x \x = ....
    • 嗨@Daniel,谢谢。但是,我不能说我理解您在个人意见中的意思。你能用不同的词写出来,甚至试着用一个例子来说明吗?
    • @tomas 好吧,我想当它归结为它时,我只是重述第一段。但是我要说明的一点是,如果您有一个带有许多参数的函数,每个参数都是一个模式,例如foo (Person name age id) (Person name' age' id') (Company name location ceo) 或类似的东西,那么阅读此代码的人会很累去破译哪个这些变量匹配所有值并且是“特殊的”——例如您是否注意到这种模式仅在您碰巧传递给同名的人和公司时才匹配?
    • @tomas 另外,我想象有人不可避免地会说,“如果它被扩展,那么当mySuperDuperConstant 作为全局变量在范围内时,我可以匹配它也是一个隐含的相等性。例如,mySuperDuperConstant = 42; foo mySuperDuperConstant = 0; foo _ = 1 应该将 42 映射到 0,而其他所有内容都映射到 1。”。突然,问题增加了十倍:您不仅需要检查同一模式中的其他变量,还需要检查范围内的每个变量。我认为长参数列表与长全局常量列表没有太大区别。
    • @Daniel,非常好。非常感谢!
    猜你喜欢
    • 2012-04-30
    • 1970-01-01
    • 1970-01-01
    • 2016-01-28
    • 1970-01-01
    • 1970-01-01
    • 2016-01-04
    • 2012-03-26
    • 1970-01-01
    相关资源
    最近更新 更多