Suppose you have a serializer/deserializer type class
class SerDes a where
ser :: a -> ByteString
des :: ByteString -> a
and it turns out that it's crucial to have a special helper function for each type a, e.g.
compress :: ByteString -> ByteString -- actually varies with the original type
I see compress as a function that I would like to associate with each a that is a SerDes. (The word "associate" is probably a bad choice, and the reason why internet searches yield nothing.)
The example is not as contrived as it looks, for example when decompress is an optional
feature of the serializer/deserializer. (Yes, the helper could be avoided by augmenting
ser with a switch that controls the compression, ser:: a -> Bool -> ByteString, or better use a Config record. But let's stick with the example.)
One way to do this is a 'dummy' class, a singleton:
data For a = For
Then this will work:
class SerDes a where
ser :: a -> ByteString
des :: ByteString -> a
compress :: For a -> ByteString -> ByteString
and a compress for a would be instantiated as
compress (For :: For MyType) input = ...
Another way, somewhat unusual, would be to stick all the functions in a record.
data SerDes a = SerDes { ser :: a -> ByteString
, des :: ByteString -> a
, compress :: ByteString -> ByteString
}
Are there any other ways to "associate" the compress function with the type a?