1

在 Richard Bird 的书“Introduction to Functional Programming Using Haskell”第二版中做练习。在以下代码的最后一行中,我收到错误:

"Parse error in pattern (n `times` Succ m)

请注意,在 的定义中接受了相同的模式(m 和 n 互换)times。为什么我会收到此错误?

    data Nat = Zero | Succ Nat
    deriving (Eq, Ord, Show)

    plus :: Nat -> Nat -> Nat
    m `plus` Zero = m
    m `plus` Succ n = Succ (m `plus` n)

    m `times` Zero = Zero
    m `times` Succ n = (m `times` n) `plus` m

    divide :: Nat -> Nat -> Nat
    Zero `divide` m = Zero
    (n `times` Succ m) `divide` n = Succ m
4

1 回答 1

3

你得到一个解析错误

(n `times` Succ m) `divide` n = Succ m

因为定义函数的参数必须是模式,即

  • 通配符_
  • 变量标识符foo
  • 构造函数应用程序(一个值构造函数应用于其数量要求的多个模式)
  • 带标签的模式F{field1 = value1, ..., fieldN = valueN}(如果构造函数F是使用命名字段语法定义的)
  • 一个字面量1"foo"
  • 否定字面量-1
  • 元组模式,(1,2)
  • 列表模式[1,2]
  • 带括号的模式(pat),哪里pat是模式
  • 一个惰性模式, ,模式~pat在哪里pat

而且这里的第一个参数不是模式,而是非构造函数的函数应用。

模式允许解构值,但普通函数应用程序不允许。对于您的问题,如果您有

12 `divide` 4

- 调用函数时可用的只是值,而不是获取方式 - 您尝试的函数定义将要求编译器考虑该值以检查它是否可以以给定的形式编写。

该行中的另一个问题是您使用了n两次标识符,但任何变量标识符在模式匹配中只能出现一次。

请注意,相同的模式(与mn互换)在 的定义中被接受times

在定义中

m `times` Succ n = (m `times` n) `plus` m

该函数times是为某些类型的参数定义的。整个左侧不是一个模式,我们有两个模式m- 一个匹配每个参数并将其绑定到名称的变量模式m- 和Succ n(包含嵌套变量模式n)。

定义的左侧由定义的名称 ( times) 和两个参数模式组成。

在 的定义中divide,需要相同的结构、要定义的名称以及参数的两种模式。

(n `times` Succ m) `divide` n = Succ m

因此,当解析器遇到左括号时,它需要一个带括号的模式。但它发现

     n          `times`            Succ m
pattern infix-function-application pattern

那的表达式树的顶部节点是times,它不是构造函数。因此,括号之间的部分不能被解析为模式。

于 2012-12-13T22:58:17.117 回答