【问题标题】:Why are the concatenation operator @ or arithmetic operators not legal pattern constructors?为什么连接运算符 @ 或算术运算符不是合法的模式构造函数?
【发布时间】:2020-08-14 19:53:59
【问题描述】:

在 Ullman 的 SML 书中

还有一些其他的模式在机器学习中是有意义的,但是是非法的。 例如,我们可能期望能够使用 连接运算符 @ 或算术运算符。

示例 3.20:我们可能希望能够将列表分解为最后一个 元素和列表的其余部分。例如,我们可能会尝试 通过

计算列表的长度
fun length(nil) = 0
| length(xs@[x]) = 1 + length(xs);
Error: non-constructor applied to argument in pattern: @
Error: unbound variable or constructor: xs

但是,正如我们所见,xs@ [x] 模式是不合法的,并且 触发两条错误消息。第一条消息抱怨@ 是 不是合法的模式构造函数。

顺便说一句,如果我们尝试使用,我们会收到一对类似的错误消息 用于构造模式的算术运算符。例如,

fun square(0) = 0
| square(x+l) = 1 + 2*x + square(x);

同样是错误的,即使它基于正确的归纳 x^2 的定义。

连接运算符 @ 或算术运算符不是合法的模式构造函数这一事实是有意设计的吗? 为什么会这样?

在大多数其他具有模式匹配的语言中也是如此吗?

谢谢。

【问题讨论】:

  • 我试图让这个问题更加集中在一种语言上。我相信在“大多数其他语言”中询问模式匹配的变化使其过于广泛,因此会相应地投票。我欢迎回滚到更具体的问题。

标签: pattern-matching sml ml


【解决方案1】:

是的,这是故意的。

@ 将允许模棱两可的模式。如果您允许它作为一种模式,那么下面的含义应该是什么?你在哪里拆分输入列表?

fun foo (a @ b) =
  Int.max (List.length a, List.length b)

val x = foo [1,2,3,4,5]  (* ??? *)

+ 也有类似的问题。将整数作为参数并在模式x+y 上定义的函数可以选择与参数相加的任意两个值xy,因此模式的含义是不明确的。溢出问题使这进一步复杂化......例如如果你有一个函数fun f (x+1) = ...,然后将最小整数作为f 的参数,会发生什么?

【讨论】:

    【解决方案2】:

    模式匹配只能检查values的结构,不能反转任意表达式。 5 是一个值。但3 + 2 不是,它是一个表达式,产生一个值。

    同样,C(x, y) 是任何作为数据类型构造函数的 C 的值,以及任何本身是值的 xy 的值。列表只是这种情况的一个实例::: 是一个数据类型构造函数,列表类型预定义为

    datatype 'a list = nil | :: of 'a * 'a list
    

    (而[x,y,z] 符号只是x :: y :: z :: nil 的简写。)

    同样,x @ y 不同,因为@ 是执行计算的函数,而不是构造函数。模式匹配不能向后运行函数。

    从概念上讲,值形成树,例如,5 :: nil 是树,其根是 :: 构造函数,其两个叶子是 5nil。模式匹配仅描述这些树的可能解构,而不是对树的计算。结果是每个模式都是明确的,并且匹配性能与模式的大小成线性关系。

    是的,所有语言都是如此。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-20
      • 1970-01-01
      • 2012-11-30
      • 1970-01-01
      • 2011-05-21
      • 2015-02-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多