I use Haskell and Functional Graph Library to represents graphs. There are two ways to compare graphs, directly, over function equal, or over another function, i wrote, isIsomorph. I want to use hash map to collect graphs. To do so I have to create instance of class Eq for my graphs. But I need two hash maps, first for graphs that compared by function equal, and second for graphs that compated by function isIsomorph.
If I do
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
I have got an expected error
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
Because of type decalration is only wrap.
I can use another way
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
That is correct but I have used an "heavy" type constructor data, this way is also inconvenient, I have to got graphs from fragments by addtional function fgraph.
Is there any "beautiful" and "true" way to divide this types in various parts of code?
The "beautiful" and "true" way to divide this types in various parts of code? is to use newtype
instead of data
: For all type system purposes, they are different (in particular, you can define different type class instances), but they share the same run-time representation and there is no additional like with 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
You will still need to convert between graphs and fragments when trying to use graph functions on fragments.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With