I’m using Generic to write a simple parser. The task is pretty much equivalent to write a Read
instance for a simple sum type. The problem is, you need to have the constructor name (to check the input string against). You can do so by using conName
but it requires an object of the type you are trying to construct (so you don’t have it ).
For a Show
instance, there is no problem (I can call conName
on the argument) but for Read
like how do you do ?
The best I come with is
class GHeader f where
gParse :: Text -> [Text] -> Either Text (f a)
instance forall a c. (Constructor c, GHeader a) => GHeader (C1 c a) where
gParse header tags = if unpack header == dropEnd 1 cname
then M1 <$> (gParse header tags)
else Left $ pack $ cname ++ " invalid header"
where cname = conName @c (error "dummy to get type constructor")
The problem is in relies on TypeApplication
, ScopedTypeVariables
and creating a “dummy” object (with `error “dummy to get type constructor”). Surely there must be something simpler.