23

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

4

4 回答 4

42

这称为非线性模式。不久前,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
于 2009-07-24T18:36:49.760 回答
14

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

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

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

于 2009-07-24T17:34:06.503 回答
0

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

于 2014-04-12T13:29:08.533 回答
-3

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

https://github.com/egison/egison

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

(define $plus
  (match-lambda [integer integer]
    {[[$a ,a] (* a 2)]
     [[$a $b] (+ a b)]}))
于 2014-12-25T02:22:55.197 回答