This can be done using, for example, the regular library . To work with this library, some language extensions are usually required:
{-
{-
{-
{-
{-
import Control.Applicative
import Generics.Regular
, -- -: ., , uu-parsinglib parsec, , .
newtype Parser a = Parser {runParser :: ReadS a}
instance Functor Parser where
fmap f p = Parser $ \s -> [(f x, s') | (x, s') <- runParser p s]
instance Applicative Parser where
pure x = Parser $ \s -> [(x, s)]
p <*> q = Parser $ \s ->
[(f x, s'') | (f, s') <- runParser p s, (x, s'') <- runParser q s']
instance Alternative Parser where
empty = Parser $ \_ -> []
p <|> q = Parser $ \s -> runParser p s ++ runParser q s
( , type ReadS a = String -> [(a, String)].)
pSym :: Char -> Parser Char
pSym c = Parser $ \s -> case s of
(c' : s') | c == c' -> [(c', s')]
_ -> []
pInt :: Parser Int
pInt = Parser reads
pFloat :: Parser Float
pFloat = Parser reads
, :
class Parseable a where
getParser :: Parser a
instance Parseable Int where
getParser = pInt
instance Parseable Float where
getParser = pFloat
, :
data Record = Record {i :: Int, f :: Float}
instance Parseable Record where
getParser = Record <$> pInt <* pSym ' ' <*> pFloat
, ?
Record ( . regular):
type instance PF Record = K Int :*: K Float
Record type Regular:
instance Regular Record where
from (Record n r) = K n :*: K r
to (K n :*: K r) = Record n r
:
class ParseableF f where
getParserF :: Parser a -> Parser (f a)
instance ParseableF (K Int) where
getParserF _ = K <$> pInt
instance ParseableF (K Float) where
getParserF _ = K <$> pFloat
instance (ParseableF f, ParseableF g) => ParseableF (f :*: g) where
getParserF p = (:*:) <$> getParserF p <* pSym ' ' <*> getParserF p
( , , .)
, Regular ( ParseableF ) :
instance (Regular a, ParseableF (PF a)) => Parseable a where
getParser = to <$> getParserF getParser
. Parseable (.. , Int, Float , , Record), . :
> runParser (getParser :: Parser Record) "42 3.14"
[(Record {i = 42, f = 3.14},"")]
. , , . , . . , Template Haskell, Regular . , . .