
On Thu, Feb 18, 2016 at 06:50:26PM -0800, Jeffrey Brown wrote:
I use FGL, which (roughly) defines type Gr a b as a graph on nodes of type a and edges of type b.
Suppose you wanted a graph that described which people own which hamsters, knowing only their name. You would have to make node and edge types like this: data GraphNode = Person String | Hamster String data GraphEdge = Has where the strings represent their names.
Suppose then you wanted to write a function that, given a person, returns the names of all their hamsters. To make sure the call makes sense, the function would have to first check that the input is in fact a person. Since persons and hamsters are both constructors of the same type,
Actually, I think the problem is that "String" is the same type as "String". Maybe this? data GraphNode = NodePerson Person | NodeHamster Hamster Then you can expose an API that just accepts a Person, and let the find-function take care of constructing the proper start value (i.e. a NodePerson). personHamsters :: MyGraph -> Person -> [Hamster] personHamsters g p = ... where startNode = NodePerson p Still, you'll have to do case evaluation at *some* point, right? If you have two types of nodes, and you're zooming around the graph, you'll have to stop and dereference each node to know what to do next. At least by hiding the details behind the API, your search function will be total.