I have a polymorphic function like:
convert :: (Show a) => a -> String
convert = \" [label=\" ++ (show a) ++ \"]\"
But sometimes I w
You may not be asking the right thing. I'm going to assume that you either have a graph whose nodes are all Map
s or you have a graph whose nodes are all something else. If you need a graph where Map
s and non-maps coexist, then there is more to your problem (but this solution will still help). See the end of my answer in that case.
The cleanest answer here is simply to use different convert
functions for different types, and have any type that depends on convert
take it as an argument (a higher order function).
So in GraphViz (avoiding redesigning this crappy code) I would modify the graphviz
function to look like:
graphvizWithLabeler :: (a -> String) -> ... -> String
graphvizWithLabeler labeler ... =
...
where sa = labeler a
And then have graphviz
trivially delegate to it:
graphviz = graphvizWithLabeler sl
Then graphviz
continues to work as before, and you have graphvizWithLabeler
when you need the more powerful version.
So for graphs whose nodes are Maps
, use graphvizWithLabeler processMap2FancyKVString
, otherwise use graphviz
. This decision can be postponed as long as possible by taking relevant things as higher order functions or typeclass methods.
If you need to have Map
s and other things coexisting in the same graph, then you need to find a single type inhabited by everything a node could be. This is similar to TomMD's suggestion. For example:
data NodeType
= MapNode (Map.Map Foo Bar)
| IntNode Int
Parameterized to the level of genericity you need, of course. Then your labeler function should decide what to do in each of those cases.
A key point to remember is that Haskell has no downcasting. A function of type foo :: a -> a
has no way of knowing anything about what was passed to it (within reason, cool your jets pedants). So the function you were trying to write is impossible to express in Haskell. But as you can see, there are other ways to get the job done, and they turn out to be more modular.
Did that tell you what you needed to know to accomplish what you wanted?