模式匹配相同的值

时间:2009-07-24 17:25:50

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

我只是想知道是否可以使用函数式编程语言(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而不是找出函数是否具有相同的值。是否有任何技巧可以表明我想要匹配的变量会多次出现?

5 个答案:

答案 0 :(得分:40)

这称为非线性模式。不久前,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

答案 1 :(得分:14)

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

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

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

答案 2 :(得分:0)

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

答案 3 :(得分:-1)

Haskell没有统一。

答案 4 :(得分:-1)

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

https://github.com/egison/egison

在我的语言中,您的plus函数的编写如下。

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