【发布时间】:2018-12-31 04:33:24
【问题描述】:
这是我的数据结构
data Ex =
P String
| (:←) Ex
它具有p == ←←p 的属性。我的自定义 Eq 和 Ord 实例尝试定义相同的。但是,我看到 test3(从 [p,←←p, ←p] 创建的集合)和 test4(从 [p, ←p, ←←p] 创建的集合)的结果不一致。结果如下图:
*Test> test3
fromList [←q,←←q]
*Test> test4
fromList [q,←q,←←q]
请注意,test3 和 test4 仅在创建集合的元素顺序上有所不同。然而,结果却不同。
我认为使用 Data.Set.fromList 创建集合的顺序并不重要。有人可以帮我找出我的 Eq 或 Ord 实例的错误吗?完整代码如下,使用 GHC 8.4.3 编译。
module Test where
import Data.Set as S
data Ex =
P String
| (:←) Ex
instance Show Ex where
show (P s) = s
show ((:←) e) = "←" ++ (show e)
instance Eq Ex where
(P s1) == (P s2) = s1 == s2
(:←) e1 == (:←) e2
| e1 == e2 = True
| otherwise = False
e1 == (:←) e2
| e1 == e2 = False
| (:←) e1 == e2 = True
| otherwise = False
(:←) e1 == e2
| e1 == e2 = False
| e1 == (:←) e2 = True
| otherwise = False
elength :: Ex -> Int
elength (P s) = length s
elength ((:←) e) = elength e + 1
instance Ord Ex where
compare e1 e2
| e1 == e2 = EQ
| otherwise = if (elength e1) <= (elength e2) then LT
else GT
-- Check that ←q == ←←q
test2 = S.fromList [(:←) ((:←) (P "q")), P "q"]
-- output should be : {←←q, ←q}
test3 = S.fromList [P "q", (:←) ((:←) (P "q")), (:←) (P "q")]
-- output should be same as that of test3 : {←←q, ←q}
test4 = S.fromList [P "q", (:←) (P "q"), (:←) ((:←) (P "q"))]
编辑:
-
请注意,如果我修改
elength定义来处理这种情况,那么不一致就会消失。elength ((:←) ((:←) e)) = elength e 在
q和←←q的情况下,我的elength度量和==定义可能不一致。我还是想知道他们到底哪里出了问题
【问题讨论】:
-
为什么要使用这个
:←构造函数?使用一元中缀运算符比使用简单的 Not 构造函数要痛苦得多。 -
也许是这样。这是一个更大的项目的一部分,其中还有其他几个一元运算符,在代码中以视觉方式区分它们会有所帮助。