【问题标题】:What sort of iterations does GHC do while compiling patterns?GHC 在编译模式时做了哪些迭代?
【发布时间】:2016-11-30 03:52:10
【问题描述】:

我刚刚编写了一个用于在井字游戏中移动的函数。我想推动模式匹配。所以我写了 9 个makeAMove 子句。每个人都有一个井字游戏板,不同的空间由空符号指定。它看起来像这样。

makeAMove [[E,   m12, m13],
           [m21, m22, m23],
           [m31, m32, m33]] X 1 1 = ...

此子句将在棋盘的左上角放置一个 X。 X、O 和 E 被定义为标记。

data Mark = X |  O | E deriving (Eq, Show)

当我加载文件时,我会收到此警告消息。

warning:
    Pattern match checker exceeded (2000000) iterations in
    an equation for ‘mov1’. (Use -fmax-pmcheck-iterations=n
    to set the maximun number of iterations to n)

我的问题是出于好奇。模式匹配器在做什么类型的迭代?为什么需要这么多?

当我将子句的数量限制为 5 个并将其余部分放在另一个默认情况下链接的函数中时,没有问题。

【问题讨论】:

  • 这要么是一个奇怪的 ghc 错误,要么是你的代码中非常奇怪的东西。请包含足够的代码来重现。你使用的是什么版本的 ghc?
  • 您能否发布mov1 的模式,这似乎是导致错误的绑定?
  • 这似乎与模式穷举检查器明显相关。由于编译器的那部分最近受到了很多黑客攻击,因此了解 @jberryman 建议的 GHC 版本非常重要

标签: haskell pattern-matching ghc


【解决方案1】:

这是一个 MCVE:

{-# OPTIONS -Wall #-}
data T = O | A | B | C | D | E

f :: T -> T -> T -> T -> T -> T -> T -> T -> T -> ()
f O _ _ _ _ _ _ _ _ = ()
f _ O _ _ _ _ _ _ _ = ()
f _ _ O _ _ _ _ _ _ = ()
f _ _ _ O _ _ _ _ _ = ()
f _ _ _ _ O _ _ _ _ = ()
f _ _ _ _ _ O _ _ _ = ()
f _ _ _ _ _ _ O _ _ = ()
f _ _ _ _ _ _ _ O _ = ()
f _ _ _ _ _ _ _ _ O = ()

结果:

ExhaustivePattern3.hs:5:5: warning:
    Pattern match checker exceeded (2000000) iterations in
    an equation for ‘f’. (Use -fmax-pmcheck-iterations=n
    to set the maximun number of iterations to n)

我猜检查器太急切地试图生成反例:有许多不匹配的模式,随着参数的数量呈指数增长。

确实,在第一次匹配之后,不匹配的情况是

A _ _ _ _ _ _ _ _
B _ _ _ _ _ _ _ _
...
E _ _ _ _ _ _ _ _

然后在第二个之后,这扩展为:

A A _ _ _ _ _ _ _
A ...
A E _ _ _ _ _ _ _
B A _ _ _ _ _ _ _
B ...
B E _ _ _ _ _ _ _
...
E A _ _ _ _ _ _ _
E ...
E E _ _ _ _ _ _ _

等等。这呈指数级增长。

【讨论】:

  • 很好(或者可能不太好)的发现。您是否已经/是否已经为此打开了票?
  • @Alec 我没有检查。如果缺少,请随时检查/添加。
  • @Alec 看起来this 是最相关的票证。
  • 抱歉没有早点回复。这是一个很好的例子,类似于(并且比我的代码更简单)。
  • 我正在尝试这个例子,即使你添加了一行f _ _ _ _ _ _ _ _ _ = (),也会给出相同的警告。我希望在这种情况下不会启动模式匹配检查。那是 ghc 错误吗?
猜你喜欢
  • 2016-03-14
  • 2010-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-11
  • 1970-01-01
相关资源
最近更新 更多