2016-11-30 53 views
7

我剛剛寫了一個在井字遊動的功能。我想推動模式匹配。所以我寫了9 makeAMove條款。每個都有一個Tic-Tac-Toe板,由空符號指定不同的空間。它看起來像這樣。GHC在編譯模式時會做什麼樣的迭代?

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,並將其餘部分放在另一個由默認情況鏈接的函數中時,沒有任何問題。

+5

這是一個奇怪的ghc錯誤或者代碼中真正奇怪的東西。請包含足夠的代碼來重現。你使用的是什麼版本的ghc? – jberryman

+2

你可以發佈'mov1'的模式,這似乎是導致錯誤的綁定? –

+3

這似乎與模式窮舉檢查器有明確的關係。由於那部分編譯器最近受到了很多黑客攻擊,因此知道GHC版本非常重要,因爲@jberryman建議使用 – dfeuer

回答

8

這裏有一個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 _ _ _ _ _ _ _ 

等。這種指數增長。

+0

Nice(或者不太好)找到。你有沒有開過這張票? – Alec

+0

@Alec我沒有檢查。如果缺少,請隨時檢查/添加它。 – chi

+2

@Alec它看起來像[this](https://ghc.haskell.org/trac/ghc/ticket/11822)是最相關的票。 –