I am trying to represent weighted edges. I eventually want to have OutE to be an instance of Eq and Ord, with the constraint that etype is an instance of Eq and Ord. Assume I have following file as temp.hs:
data (Ord etype)=> OutE vtype etype = OutE {destVertex:: vtype, edgeValue::etype}
applyFunBy accessor ordfun = (\x y -> (ordfun (accessor x) (accessor y)))
instance Eq (OutE vtype etype) where
--(==) :: Ord etype => (OutE vtype etype) -> (OutE vtype etype) -> Bool
--(/=) :: Ord etype => (OutE vtype etype) -> (OutE vtype etype) -> Bool
(==) = applyFunBy edgeValue (==)
(/=) = applyFunBy edgeValue (/=)
when I load this in ghci, I get the following errors:
temp.hs:10:19:
Could not deduce (Ord etype)
from the context (Eq (OutE vtype etype))
arising from a use of `edgeValue' at temp.hs:10:19-27
Possible fix:
add (Ord etype) to the context of the instance declaration
In the first argument of `applyFunBy', namely `edgeValue'
In the expression: applyFunBy edgeValue (==)
In the definition of `==': == = applyFunBy edgeValue (==)
temp.hs:11:19:
Could not deduce (Ord etype)
from the context (Eq (OutE vtype etype))
arising from a use of `edgeValue' at temp.hs:11:19-27
Possible fix:
add (Ord etype) to the context of the instance declaration
In the first argument of `applyFunBy', namely `edgeValue'
In the expression: applyFunBy edgeValue (/=)
In the definition of `/=': /= = applyFunBy edgeValue (/=)
Failed, modules loaded: none.
If include the lines for the type signatures for (==) and (\=), I get:
temp.hs:6:1:
Misplaced type signature:
== ::
(Ord etype) => (OutE vtype etype) -> (OutE vtype etype) -> Bool
temp.hs:7:1:
Misplaced type signature:
/= ::
(Ord etype) => (OutE vtype etype) -> (OutE vtype etype) -> Bool
You limited
etypeto beOrdin the defintion ofOutE:But in the
Eqinstance, you’re actually trying to define the instance for anyetypeunrestrictedly.Of course this doesn’t work since
OutEitself is just defined forOrd etypes, thus you’ll have to add the typeclass constraint to the instance definition as well.Note that one definition of either
==or/=is sufficient for the typeclass to work.Note that it’s often easier and therefore considered better style not to have typeclass constraints on
data-types, but just on instances/methods that actually require the functionality of the typeclass.In many cases, one does not need the constraint and just ends up with unnecessarily clumsy type signatures.
Take e.g. some ordered map type
Ord key => Map key value.What if we just want to list all keys? Or get the number of elements? We don’t need the keys to be
Ordfor these, so why not just leave the map unrestricted with simpleand just add the typeclass when we really need it in a function like