Question

When answering a question with a suggestion to use GADTs, some questions with regards to performance came up in the comments. The question involved a typeclass PlotValue:

class PlotValue a where
    value :: a -> Double

and my answer suggested using a GADT Input:

data Input where
    Input :: (PlotValue a, PlotValue b) => Maybe a -> Maybe b -> Input

but the details are, I suppose, immaterial.

I'm wondering about two aspects of performance:

Time: Are there any runtime costs incurred by a pattern match like

case x of
    Input (Just a) (Just b) -> value a * value b
    _ -> 0.0

over and above the normal costs matching two Maybe values?

Space: How much storage overhead does a value of type Input carry? My guess is that it carries the two PlotValue dictionaries around for each and every value of type Input (a 'pointer' each?), meaning that a [Input] will be much more inefficient in terms of memory use than using (Just Double, Just Double) or, better yet, (# #Double, #Double #) - if you store the results of value in a normal or unpacked tuple.

So, while I love the expressiveness GADTs give me, I've never thought about the performance aspects much. Can anyone tell me more about this (and any other hidden costs I might not be aware of)?

No correct solution

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top