为什么haskell解释器给我这个解析错误?

时间:2012-12-13 22:54:34

标签: haskell pattern-matching parse-error

在Richard Bird的书“使用Haskell进行功能编程简介”第二版中进行练习。在以下代码的最后一行中,我收到错误:

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

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

    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

1 个答案:

答案 0 :(得分:3)

您在

上遇到解析错误
(n `times` Succ m) `divide` n = Succ m

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

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

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

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

12 `divide` 4

- 调用函数时所有可用的值是值,而不是它是如何获得的 - 您尝试的函数定义将要求编译器对值进行因式分析以检查它是否可以以给定的形式写入。

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

  

请注意m的定义中接受了相同的模式(ntimes互换)。

在定义中

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,它不是构造函数。因此,括号之间的部分不能被解析为模式。