, Example Haskell. , return putStrLn Example (String -> IO ()), , Example .
, , foo bar, >> ( ) *. Backus-Naur :
<program> ::= "" | <expr> "\n" <program>
<expr> ::= "foo " <integer> | "bar " <string>
...
type Parser = Parsec String ()
int :: Parser Int
int = fmap read (many1 digit)
parseFoo :: Parser (Example ())
parseFoo = string "foo " *> fmap foo int
parseBar :: Parser (Example Int)
parseBar = string "bar " *> fmap bar (many1 alphaNum)
... ?
parseExpr :: Parser (Example ???)
parseExpr = parseFoo <|> parseBar
parseFoo parseBar , <|> :: Alternative f => f a -> f a -> f a. , , , : , . ", ", ; Haskell , , , .
, <|> . Example, . †
data Ex a = forall i. Wrap (a i)
parseExpr :: Parser (Ex Example)
parseExpr = fmap Wrap parseFoo <|> fmap Wrap parseBar
typechecks, Example, . , , , - Example: (), Int, parseFoo parseBar. - , Example GADT, , , , a Int ().
data Ty a where
IntTy :: Ty Int
UnitTy :: Ty ()
data (a :*: b) i = a i :&: b i
type Sig a b = Ex (a :*: b)
pattern Sig x y = Wrap (x :&: y)
parseExpr :: Parser (Sig Ty Example)
parseExpr = fmap (\x -> Sig UnitTy x) parseFoo <|>
fmap (\x -> Sig IntTy x) parseBar
Ty (- ) "singleton" , Example. IntTy, , a ~ Int; UnitTy, , a ~ (). ( , , .) :*:, functor product, , ; , Ty Example.
Sig - - . : , , , .
, Sig Either (Example Int) (Example ()) - - - , - , re (, , ) .
. , .
parseProgram :: Parser (Sig Ty Example)
parseProgram = fmap (foldr1 combine) $ parseExpr `sepBy1` (char '\n')
where combine (Sig _ val) (Sig ty acc) = Sig ty (val >> acc)
, , . . , - , , , . , , .
* , ?
† Ex :*: ,