I have written my own implementation of a graph based on adjacency matrices and made instance of the Read class.
My graph takes a type as input which will be the type of the edges.
If I try expression like
read " - - 8 \n - 9 - \n 1 2 3" :: GraphADJ Int
it works just fine (it’s a graph with 3 nodes, and the edge from first node to the third, from the second to the second and from the third to all the nodes).
What I wanted to do is to be able to not tell the type inference the type of the edges, but to put them into a context (like in read"4"+3).
I have the function insertEdge which takes a graph, a couple of nodes and the new edge.
insertEdge :: Graph g n e => g -> (n, n) -> e -> g
(Graph is the general class for the graph which GraphADJ is made instance of)
So when I try to do
insertEdge (read " - - 8 \n - 9 - \n 1 2 3" :: GraphADJ Int) (1,2) 3
it works just fine, but if I don’t make the type explicit, I get the error
Ambiguous type variables .
Did I forget something in the Read or a I missing something?
The problem is compiler does not have enough info to infer type for read.
Even if you provide type info for
ntoIntandetoIntcompiler still does not have information ofg. All it knows thatgis a type with an instance forGraph g Int Int. It still can not infergeven if there is single type which inhabit such an instance.Compiler can not automatically see that in the current scope there is only on such type which has such a instance as allowing such behavior might result in breaking of code by importing modules.
So the solution would be either to provide explicit signature or to make a specialized version of
insertEdgeproviding explicit concrete types to provide enough information forread. The latter would be useful if you are using it for the same type at more than one place.