I think you may be confused about the following: type NodeConcept* = concept n # LINE A $n is string GraphConcept*[NodeConcept] = concept g # LINE B type NodeType = NodeConcept g.nodes() is seq[NodeType] Run
The `NodeConcept` on line B is actually _not_ the same as the `NodeConcept` on line A. It's just another name for a type parameter. The following works: type NodeConcept* = concept n $n is string GraphConcept*[N] = concept g type NodeType = N g.nodes() is seq[NodeType] Graph*[N] = object mynodes*: seq[N] Node* = object n*: int proc nodes*[N](g: Graph[N]): seq[N] = g.mynodes proc shortest_path*[N](g: GraphConcept[N]): seq[g.NodeType] = g.nodes proc `$`(n: Node): string = $n.n let nodes2 = @[Node(n:1), Node(n: 2)] let g = Graph[Node](mynodes: nodes2) echo shortest_path(g) Run And it also fails to compile if you remove the `$` proc for Node, which is what I think you were hoping would happen.