I’m writing a graph library to learn more about building slightly larger things in Haskell, and I’m coming across an issue.
Basically, I’m trying to define Edges as a set of two points, a from point and a to point. But, I’ve got multiple types of edges (Weighted/not), and I do not want them to be able to mix in graphs.
So, the idea I had was to make a couple of new classes, Weighted and Edgy, in order to be able to achieve the amount of polymorphic behavior I’m striving towards. Both types of Edge will be Edgy, but only the Weighted Edge type will be Weighted.
The Weighted class is simple, because it only has to modify the entire object. This is what it looks like:
class Weighted a where
modifyWeight :: (Unbounded Int -> Unbounded Int) -> a -> a
where Unbounded is a Num type I threw together to support Infinitely large and small numbers. It’s simple enough, though, because I only have to return an a.
What I’m stuck on is getting the Edgy class to return something of the type of the class type (??? Not really sure how to put this, inner type, maybe?). To make this clearer, here’s what I’m working with, might make more sense:
class Edgy a where
to :: a -> Vertex a
from :: a -> Vertex a
where Vertex is a wrapper class — the Edge declarations that I’m trying to make here here:
data Edge a = Edge (Vertex a) (Vertex a) deriving (Show, Eq)
data WEdge a = WEdge (Vertex a) (Vertex a) (Unbounded Int) deriving (Show, Eq)
So, what I’m really trying to do is say “Okay, if you’re a member of the Edgy class, you should be able to return a Vertex of the type of the Edge“.
However, GHC doesn’t like this, because the a type in Edgy ends up being Edge a instead of a, and I’m not sure how to get it to “descend” into the class to pull that type out in order to return it.
If any of this is unclear, please leave a comment.
Any help is greatly appreciated; I’m stumped!
Thanks!
You may want to use type constructor classes rather than type classes