Jak mogę automatycznie czerpać instancji Read
dla tego GADTs:wynikających lektura Instancje dla 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
Chodzi o to, że Bar
jest rodzajem serializacji.
mogę napisać instancji Read
następującym fragmencie lub parsec, ale biorąc pod uwagę, że mam wiele podobnych typów do TypeDec
i Bar
w różnych modułach To 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 (== ' ')
Jest to całkowicie wykonalne przy użyciu szablonu Haskell. Wystarczy użyć podejścia wspomnianego przez @dfeuer (tzn. Używając 'case' zamiast' GHC.Read.choose'). – Alec
@ Czy znasz jakiś przykład/samouczek do wyprowadzania instancji 'Read' za pomocą szablonu Haskell? – homam
[This] (https://wiki.haskell.org/Template_haskell/Instance_deriving_example) wygląda dobrze. – Alec