2017-11-11 56 views
0

我是Haskell的新手,正在寫我的第一個數據結構。Haskell數據「錯誤 - 控制堆棧溢出」

data Nat = Null | N Nat 

例如:5N (N (N (N (N Null))))

我不得不從Show, Eq, Ord, Num, Enum

創建實例,我寫Eq已經和它的作品。

instance Eq Nat where 
    (==) Null Null = True 
    (==) (N Null) (N Null) = True 
    (==) Null (N Null) = False 
    (==) Null (N xs) = False 
    (==) (N xs) (N xs2) = xs == xs2 

但是,當我在擁抱中嘗試這個,它給了我一個錯誤(「錯誤 - 控制堆棧溢出」)。

我無法繼續。

(N (N Null)) :: Nat 

我在想什麼?

+2

我想這裏的問題是你的'Show'。如果這是你的查詢,你永遠不會調用'(==)'。還要注意,dat擁抱基本上已經死了(自2006年iirc以來),所以也許你最好使用GHC。 –

+0

你也忘了'(N x)== Null'的情況。 –

+0

謝謝你的回答和時間!但在ghci中它仍然是一個堆棧溢出 –

回答

5

你沒有涵蓋所有的情況。此外,您還可以通過進行最後的「追趕其他地區」情況如下簡化定義:

instance Eq Nat where 
    (==) Null Null = True 
    (==) (N xs) (N xs2) = xs == xs2 
    (==) _  _  = False 

我不知道,不過,爲什麼你的代碼給你一個堆棧溢出。它可能會給你一個非詳盡的匹配錯誤。

無論如何,請注意擁抱現在已經過時 - 它已經超過10年沒有更新。您應該切換到GHC並使用ghci而不是Hugs。


如果仍然出現堆棧溢出,很可能是這個問題是在Show情況下,在那裏你可以定義無限遞歸,如威廉·Onsem上述指出。

你應該使用類似

instance Show Nat where 
    show Null = "Null" 
    show (N x) = "(N " ++ show x ++ ")" 

順便說一句,注意一些標準情況下可以自動生成,以正確的方式。例如,

data Nat = Null | N Nat deriving (Show, Eq, Ord) 

應該按照預期工作。儘管如此,這是一個很好的學習練習,可以自己定義這些練習。

+0

謝謝你的回答和時間!但在ghci中它仍然是一個堆棧溢出。 > Prelude Null - >堆棧溢出 –

+0

@ Marc-AurelP。查看更新。 – chi

+0

這確實是我的Show方法。我忘了使用標籤。我不知道哈斯克爾是那麼敏感。謝謝! –