How can I automatically derive a Read
instance for this GADTs:
{-# LANGUAGE GADTs, StandaloneDeriving #-}
data TypeDec a where
TypeDecInt :: TypeDec Int
TypeDecString :: TypeDec String
deriving instance Show (TypeDec a)
data Bar where
Bar :: (Show a, Read a) => TypeDec a -> a -> Bar
deriving instance Show Bar
The idea is that Bar
is a serializable type.
I can write a Read
instance by the following snippet or by Parsec, but considering that I have many similar types to TypeDec
and Bar
in different modules this is a boilerplate:
instance Read Bar where
readsPrec _ s =
let (bar, tup) = second breaks . breaks $ s
in if "Bar" == bar then uncurry parse tup else []
where
parse :: String -> String -> [(Bar, String)]
parse tdec = case tdec of
"TypeDecInt" -> parse' TypeDecInt
"TypeDecString" -> parse' TypeDecString
_ -> const []
parse' :: (Show a, Read a) => TypeDec a -> String -> [(Bar, String)]
parse' tdec s = [(Bar tdec (read s), "")]
breaks :: String -> (String, String)
breaks = second (drop 1) . break (== ' ')