不可能將樹的高度與大于(>)和大于或等于的符號進行比較(>=)。這是我的代碼。它只是在命令處凍結tree1 >= tree2:
data Tree a = Node a [Tree a] deriving (Eq,Show)
instance (Ord a) => Ord (Tree a) where
Node a list1 >= Node b list2 = (list1 > list2) || (list1 == list2)
(Node a list1) > (Node b list2) = (list1 > list2)
t0 = Node 15 []
t1 = Node 15 []
t2 = Node 120 [t0]
tree1 = Node 130 [t1,t2]
tt0 = Node 155 []
tt1 = Node 112 [t2]
tt2 = Node 128 [t0]
tree2 = Node 110 [tt1,tt2,tt0]
uj5u.com熱心網友回復:
Ord該類的檔案包括關于“最小定義”的部分:
最小完整定義
compare | (<=)
這意味著您必須至少定義compare或之一(<=)。否則,類提供的默認定義可能會崩潰或回圈。
此外,即使它的檔案不太清楚,重要的是定義Eq和Ord兼容。如果tree3 <= tree4和tree3 >= tree4,那么你最好有tree3 == tree4。您的定義不滿足這一點,因為您的Ord實體忽略了節點的內容,但自動派生的Eq實體會比較它們。
相反,您應該撰寫自己的Eq實體和自己的最小Ord實體:
data Tree a = Node a [Tree a] deriving (Show)
instance (Eq a) => Eq (Tree a) where
Node _ list1 == Node _ list2 = list1 == list2
instance (Ord a) => Ord (Tree a) where
Node _ list1 <= Node _ list2 = list1 <= list2
在此之后,所有比較運算子都應該正常作業:
λ> compare tree1 tree2
LT
λ> tree1 == tree2
False
λ> tree1 < tree2
True
λ> tree1 <= tree2
True
λ> tree1 >= tree2
False
λ> tree1 > tree2
False
λ> tree1 == tree2
False
λ> tree1 /= tree2
True
僅供參考,您的原始定義回圈的原因有點模糊。使用您原來的錯誤定義:
data Tree a = Node a [Tree a] deriving (Eq,Show)
instance (Ord a) => Ord (Tree a) where
Node a list1 >= Node b list2 = (list1 > list2) || (list1 == list2)
(Node a list1) > (Node b list2) = (list1 > list2)
你會發現以下作業:
> Node 1 [] >= Node 2 []
True
但以下掛起:
> [Node 1 []] >= [Node 2 []]
Interrupted.
問題是Ordfor 串列的定義是根據 定義的compare,因此即使您的定義看起來只是使用>=and >,它在比較子節點串列時也在compare幕后使用。由于 的默認定義compare是根據 定義的,<=而 的默認定義<=是根據 定義的compare,因此您會在默認定義中得到一個回圈。
uj5u.com熱心網友回復:
TL;DR:定義<=。
啟用警告,它會說:
- 'compare' 或 '<=' 沒有明確的實作
- 在“Ord (Tree a)”的實體宣告中
對于Ord,您必須至少實作以下其中一項:<=或compare.
這是由于這兩個功能的標準實作Ord在hackage上可用:
compare x y = if x == y then EQ
-- NB: must be '<=' not '<' to validate the
-- above claim about the minimal things that
-- can be defined for an instance of Ord:
else if x <= y then LT
else GT
x < y = case compare x y of { LT -> True; _ -> False }
-- ...
{-# MINIMAL compare | (<=) #-}
正如你所看到的,這兩個函式是相互定義的,所以它會無限地凍結/回圈。并且最小的編譯指示用于警告,可以在檔案中看到
最小完整定義
compare | (<=)
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/482693.html
標籤:哈斯克尔
上一篇:將超過1個引數傳遞給monad
下一篇:使GCD代碼更漂亮、更簡潔
