I have a polymorphic function like:
convert :: (Show a) => a -> String
convert = \" [label=\" ++ (show a) ++ \"]\"
But sometimes I w
What you just explained is you want a function that behaves differently based on the type of the input. While you could use a data
wrapper, thus closing the function for all time:
data Convertable k a = ConvMap (Map k a) | ConvOther a
convert (ConvMap m) = ...
convert (ConvOther o) = ...
A better way is to use type classes, thus leaving the convert
function open and extensible while preventing users from inputting non-sensical combinations (ex: ConvOther M.empty
).
class (Show a) => Convertable a where
convert :: a -> String
instance Convertable (M.Map k a) where
convert m = processMap2FancyKVString m
newtype ConvWrapper a = CW a
instance Convertable (ConvWrapper a) where
convert (CW a) = " [label=" ++ (show a) ++ "]"
In this manner you can have the instances you want used for each different data type and every time a new specialization is needed you can extend the definition of convert
simply by adding another instance Convertable NewDataType where ...
.
Some people might frown at the newtype
wrapper and suggest an instance like:
instance Convertable a where
convert ...
But this will require the strongly discouraged overlapping and undecidable instances extensions for very little programmer convenience.