您如何识别 Haskell 中模式匹配表达式的复杂性?

How do you identify the complexity of a pattern matching expression in Haskell?

模式匹配很奇怪。它涉及寻找事物表示的看似简单的数学问题。

例如,对于给定的整数 b,每个整数 a 都可以用 a = bq + r 的形式表示,其中 0 <= r < b,唯一。要找到 q 和 r 需要除法算法。关键词是,"algorithm."

所以当你在 Haskell 中执行模式匹配表达式时,比如将元组表示为 (a,b),算法 运行 在幕后吗?

算法必须总是简单的,即 O(1) 或至少以某种方式记录在某处吗?

您如何保证代表的独特提升?

我可能误解了你的意思,但是有一种模式匹配算法。来自 Language Report:

3.17.2 Informal Semantics of Pattern Matching

Patterns are matched against values. Attempting to match a pattern can have one of three results: it may fail; it may succeed, returning a binding for each variable in the pattern; or it may diverge (i.e. return ⊥). Pattern matching proceeds from left to right, and outside to inside, according to the following rules:

  1. Matching the pattern var against a value v always succeeds and binds var to v.
  2. Matching the pattern ~apat against a value v always succeeds. The free variables in apat are bound to the appropriate values if matching apat against v would otherwise succeed, and to ⊥ if matching apat against v fails or diverges. (Binding does not imply evaluation.) Operationally, this means that no matching is done on a ~apat pattern until one of the variables in apat is used. At that point the entire pattern is matched against the value, and if the match fails or diverges, so does the overall computation.

  3. Matching the wildcard pattern _ against any value always succeeds, and no binding is done.

  4. Matching the pattern con pat against a value, where con is a constructor defined by newtype, depends on the value: If the value is of the form con v, then pat is matched against v. If the value is ⊥, then pat is matched against ⊥. That is, constructors associated with newtype serve only to change the type of a value.

  5. Matching the pattern con pat1 … patn against a value, where con is a constructor defined by data, depends on the value: If the value is of the form con v1 … vn, sub-patterns are matched left-to-right against the components of the data value; if all matches succeed, the overall match succeeds; the first to fail or diverge causes the overall match to fail or diverge, respectively. If the value is of the form con′ v1 … vm, where con is a different constructor to con′, the match fails. If the value is ⊥, the match diverges.

  6. Matching against a constructor using labeled fields is the same as matching ordinary constructor patterns except that the fields are matched in the order they are named in the field list. All fields listed must be declared by the constructor; fields may not be named more than once. Fields not named by the pattern are ignored (matched against _).
  7. Matching a numeric, character, or string literal pattern k against a value v succeeds if v == k, where == is overloaded based on the type of the pattern. The match diverges if this test diverges. The interpretation of numeric literals is exactly as described in Section 3.2 ; that is, the overloaded function fromInteger or fromRational is applied to an Integer or Rational literal (resp) to convert it to the appropriate type.

  8. Matching an as-pattern var@apat against a value v is the result of matching apat against v, augmented with the binding of var to v. If the match of apat against v fails or diverges, then so does the overall match.

在我链接的文档中,还有后面提到的更正式的描述。

您似乎对模式匹配的实际作用感到困惑。

机器以固定的表示形式存储所有数据。模式匹配仅允许您查询该表示是什么。

您不能使用模式匹配来(例如)确定两个任意表达式是否等价。那将需要解决停机问题,这是不可能的。您可以 数据模式匹配,而不是表达式。

例如,模式匹配可以告诉您列表是空的还是非空的。它可以告诉您列表是否按顺序包含数字 1、2、3。它 不能 告诉你 sort . map fst 是否产生与 map fst . sort 相同的结果,例如。

所以不存在"guaranteeing a unique representation"的问题;计算机已经做到了,不管你模式是否匹配。模式匹配在模式大小上是 O(n) 时间。 (忽略您可能触发的任何延迟评估,这是生成数据的代码的 属性,而不是使用数据的代码。)