I am trying to make a simple graph structure and I wrote the following. But GHG raises error and I stacked there. This is the first time I make my own typeclass so maybe I am doing something terribly wrong. Can somebody explain what is wrong?
I found a similar question but I don't think it applies to my case.: Error binding type variables in instance of typeclass
class Link l where
node :: (Node n) => l -> n
class Node n where
links :: (Link l) => n -> [l]
data (Node n) => SimpleLink n =
SimpleLink
{ simpleLinkNode :: n
} deriving (Show, Read, Eq)
instance (Node n) => Link (SimpleLink n) where
node = simpleLinkNode
data (Link l) => SimpleNode l =
SimpleNode
{ simpleNodeLinks :: [l]
} deriving (Show, Read, Eq)
instance (Link l) => Node (SimpleNode l) where
links = simpleNodeLinks
This is the error message I've got:
***.hs:13:10:Could not deduce (n ~ n1)
from the context (Node n)
bound by the instance declaration
at ***.hs:12:10-40
or from (Node n1)
bound by the type signature for
node :: Node n1 => SimpleLink n -> n1
at ***.hs:13:3-23
`n' is a rigid type variable bound by
the instance declaration
at ***.hs:12:16
`n1' is a rigid type variable bound by
the type signature for node :: Node n1 => SimpleLink n -> n1
at ***.hs:13:3
Expected type: SimpleLink n -> n1
Actual type: SimpleLink n -> n
In the expression: simpleLinkNode
In an equation for `node': node = simpleLinkNode
***.hs:21:11:Could not deduce (l ~ l1)
from the context (Link l)
bound by the instance declaration
at ***.hs:20:10-40
or from (Link l1)
bound by the type signature for
links :: Link l1 => SimpleNode l -> [l1]
at ***.hs:21:3-25
`l' is a rigid type variable bound by
the instance declaration
at ***.hs:20:16
`l1' is a rigid type variable bound by
the type signature for links :: Link l1 => SimpleNode l -> [l1]
at ***.hs:21:3
Expected type: SimpleNode l -> [l1]
Actual type: SimpleNode l -> [l]
In the expression: simpleNodeLinks
In an equation for `links': links = simpleNodeLinks
Edit 1
I tried some of Daniel's suggestions. But I couldn't make them work.
constructor class
Got: "`n' is not applied to enough type arguments"
class Link l n where
node :: Node n l => l n -> n l
class Node n l where
links :: Link l n => n l -> [l n]
multi-parameter type class (MPTC)
Got: "Cycle in class declarations (via superclasses)"
class (Node n) => Link l n where
node :: l -> n
class (Link l) => Node n l where
links :: n -> [l]
MPTC with functional dependencies
Got: "Cycle in class declarations (via superclasses)"
class (Node n) => Link l n | l -> n where
node :: l -> n
class (Link l) => Node n l | n -> l where
links :: n -> [l]
Goal (Edit 2)
What I want to implement is a directed acyclic graph structure like the following (more specifically, a Factor graph).
(source: microsoft.com)
There are two kinds of node (white circle and red square) and they connect only to the different type of node, meaning that there are two kinds of links.
I want different version of nodes and links which have data (arrays) attached to them. I also want "vanilla" DAG which has only one type of node and link. But for traversing them, I want only one interface to do that.