【问题标题】:Pattern matching identical values模式匹配相同的值
【发布时间】:2010-11-13 19:42:29
【问题描述】:

我只是想知道是否可以使用函数式编程语言 (Haskell/F#/Caml) 的模式匹配工具多次匹配相同的值。

想想下面的例子:

plus a a = 2 * a
plus a b = a + b

当使用两个相似的值(将存储在a)调用函数时,将调用第一个变体。

一个更有用的应用程序是这个(简化 AST)。

simplify (Add a a) = Mult 2 a

但 Haskell 拒绝这些代码并警告我 a 的定义冲突 - 我必须进行明确的 case/if-checks 来确定函数是否具有相同的值。有什么技巧可以表明我要匹配的变量会出现多次吗?

【问题讨论】:

  • FWIW,Mathematica 支持这一点。

标签: haskell f# functional-programming pattern-matching guard-clause


【解决方案1】:

你不能有两个同名的参数来表示它们应该相等,但是你可以使用guards来区分这样的情况:

plus a b
  | a == b    = 2 * a
  | otherwise = a + b

这更灵活,因为它也适用于比简单相等更复杂的条件。

【讨论】:

【解决方案2】:

这称为非线性模式。不久前,haskell-cafe 邮件列表上有几个关于此的主题。这里有两个:

http://www.mail-archive.com/haskell-cafe@haskell.org/msg59617.html

http://www.mail-archive.com/haskell-cafe@haskell.org/msg62491.html

底线:实施并非不可能,但为了简单起见,我们决定放弃。

顺便说一句,您不需要ifcase 来解决这个问题; (稍微)干净的方法是使用警卫:

a `plus` b
  | a == b = 2*a
  | otherwise = a+b

【讨论】:

    【解决方案3】:

    我刚刚查看了 Thomas 回答中给出的邮件列表线程,其中一个的第一个回复很有意义,并解释了为什么这种“模式”通常没有多大意义:what如果a 是一个函数? (一般不可能检查两个函数是否相等。)

    【讨论】:

    • 难道不能将a 限制为Eq
    • @gdejohn,我怀疑语义不正确。在应用f x x = x 形式的定义时,可以合理地期望 IMO 两个提交的参数是相同的值,而不仅仅是某种类型类意义上的“相等”(否则它不是甚至清楚x 的两个值中的哪一个应该f 返回)。
    【解决方案4】:

    我已经实现了一种新的函数式编程语言,可以在 Haskell 中处理非线性模式。

    https://github.com/egison/egison

    用我的语言,你的plus函数写成如下。

    (define $plus
      (match-lambda [integer integer]
        {[[$a ,a] (* a 2)]
         [[$a $b] (+ a b)]}))
    

    【讨论】:

      猜你喜欢
      • 2015-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-25
      • 1970-01-01
      • 1970-01-01
      • 2018-09-01
      相关资源
      最近更新 更多