我使用Haskell和Functional Graph Library来表示图形。有两种比较图形的方法,直接比较函数相等,或者比另一个函数,我写道, isIsomorph 。 我想使用hash map来收集图表。为此,我必须为我的图形创建类 Eq 的实例。但是我需要两个哈希映射,第一个用于按函数等于进行比较的图形,第二个用于由函数进行比较的图形isIsomorph 。
如果我这样做
type Fragment = Gr Atom Bond {-- Gr is a type constructor from the Functional Graph Library}
instance Eq (Gr Atom Bond) where
g == g1 = equal g g1
instance Eq Fragment where
g == g1 = isIsomorph g g1
我有一个预期的错误
Duplicate instance declarations:
instance [overlap ok] Eq (Gr Atom Bond) -- Defined at HLab.hs:45:10
instance [overlap ok] Eq Fragment -- Defined at HLab.hs:48:10
由于 type decalration只是换行。
我可以用另一种方式
data Fragment = Fragment {fgraph :: Gr Atom Bond}
instance Eq (Gr Atom Bond) where
g == g1 = equal g g1
instance Eq Fragment where
Fragment g == Fragment g1 = isIsomorph g g1
这是正确的,但我使用了“重型”构造函数 data ,这种方式也很不方便,我必须通过附加函数fgraph从片段中获取图形。
在代码的各个部分划分这些类型是否有“美丽”和“真实”的方法?
答案 0 :(得分:11)
在代码的各个部分划分这种类型的“美丽”和“真实”方式?是使用newtype
而不是data
:对于所有类型系统的目的,它们是不同的(特别是,您可以定义不同的类型类实例),但它们共享相同的运行时表示,并且与data
无关:
newtype Fragment = Fragment {fgraph :: Gr Atom Bond}
instance Eq (Gr Atom Bond) where
g == g1 = equal g g1
instance Eq Fragment where
Fragment g == Fragment g1 = isIsomorph g g1
当尝试在片段上使用图形函数时,您仍然需要在图形和片段之间进行转换。