#ifdef LANGUAGE_PTS_HAS_QUARKS
#ifdef LANGUAGE_PTS_HAS_PROP
#define QUARKS_EXAMPLES
#endif
#endif
#ifdef QUARKS_EXAMPLES
{-# LANGUAGE OverloadedStrings, ScopedTypeVariables, FlexibleContexts #-}
#endif
module Language.PTS.Examples.Quarks (
#ifdef QUARKS_EXAMPLES
quarkSyntaxScript,
monadScript,
#endif
) where
#ifdef QUARKS_EXAMPLES
import Language.PTS
import Language.PTS.Bound
import qualified Data.Set as Set
import qualified Data.Map as Map
hadron_ :: [Sym] -> TermInf s a
hadron_ = Hadron . Set.fromList
quarkElim_ :: Convert TermInf v => Sym -> TermInf s Sym -> TermChk s Sym -> [(Sym, TermChk s Sym)] -> v s Sym
quarkElim_ x@"_" p q qs = convert $ QuarkElim (IrrSym x) (liftH p) (Map.fromList qs) q
quarkElim_ x p q qs = convert $ QuarkElim (IrrSym x) (abstract1HSym x p) (Map.fromList qs) q
quarkSyntaxScript :: forall s m. Script s m => m ()
quarkSyntaxScript = do
comment_ "Using quarks we can form a variant of Booleans"
section_ "Type"
define_ "Boolean"
$$ sort_ typeSort
$$ Inf (hadron_ ["true", "false"])
section_ "Constructors"
define_ "True"
$$ "Boolean"
$$ Quark "true"
define_ "False"
$$ "Boolean"
$$ Quark "false"
section_ "Elimination"
define_ "if"
$$ forall_ "r" ("Boolean" ~> "r" ~> "r" ~> "r")
$$ lams_ ["r","b","t","f"]
(quarkElim_ "_" "r" "b"
[ "true" .= "t"
, "false" .= "f"
])
section_ "Examples"
define_ "not"
$$ "Boolean" ~> "Boolean"
$$ lam_ "b" ("if" @@ "Boolean" @@ "b" @@ "False" @@ "True")
example_ "not"
example_ $ "not" @@ "True"
example_ $ "not" @@ "False"
monadScript :: forall s m. Script s m => m ()
monadScript = do
section_ "Class"
defineInf_ "MonadMethods" $ hadron_ ["pure" , "fmap", "join"]
define_ "Monad'"
$$ (sort_ typeSort ~> sort_ typeSort) ~> "MonadMethods" ~> sort_ typeSort
$$ lams_ ["M","q"] (quarkElim_ "_" (sort_ typeSort) "q"
[ "pure" .= forall_ "A" ("A" ~> "M" @@ "A")
, "fmap" .= foralls_ ["A","B"] (("A" ~> "B") ~> "M" @@ "A" ~> "M" @@ "B")
, "join" .= forall_ "A" ("M" @@ ("M" @@ "A") ~> "M" @@ "A")
])
define_ "Monad"
$$ (sort_ typeSort ~> sort_ typeSort) ~> sort_ typeSort
$$ lam_ "M" (pi_ "q" "MonadMethods" $ "Monad'" @@ "M" @@ "q")
section_ "Identity"
define_ "Identity"
$$ sort_ typeSort ~> sort_ typeSort
$$ lam_ "A" "A"
define_ "MonadIdentity"
$$ "Monad" @@ "Identity"
$$ lam_ "q" (quarkElim_ "q" ("Monad'" @@ "Identity" @@ "q") "q"
[ "pure" .= lams_ ["_","x"] "x"
, "fmap" .= lams_ ["_","_","f"] "f"
, "join" .= lams_ ["_","x"] "x"
])
section_ "Proxy"
define_ "Proxy"
$$ sort_ typeSort ~> sort_ typeSort
$$ lam_ "_" (Inf Unit)
define_ "MonadProxy"
$$ "Monad" @@ "Proxy"
$$ lam_ "q" (quarkElim_ "q" ("Monad'" @@ "Proxy" @@ "q") "q"
[ "pure" .= lams_ ["_","_"] (Inf I)
, "fmap" .= lams_ ["_","_","_","_"] (Inf I)
, "join" .= lams_ ["_","_"] (Inf I)
])
section_ "Reader"
define_ "Reader"
$$ sort_ typeSort ~> sort_ typeSort ~> sort_ typeSort
$$ lams_ ["E","A"] ("E" ~> "A")
define_ "MonadReader"
$$ forall_ "E" ("Monad" @@ ("Reader" @@ "E"))
$$ lams_ ["E","q"] (quarkElim_ "q" ("Monad'" @@ ("Reader" @@ "E") @@ "q") "q"
[ "pure" .= lams_ ["A","a","e"] "a"
, "fmap" .= lams_ ["A","B","ab","ea","e"] ("ab" @@ ("ea" @@ "e"))
, "join" .= lams_ ["A","eea","e"] ("eea" @@ "e" @@ "e")
])
section_ "Polymorphic usage"
define_ "void"
$$ pi_ "M" (sort_ typeSort ~> sort_ typeSort) ("Monad" @@ "M" ~> forall_ "A" ("M" @@ "A" ~> "M" @@@ Unit))
$$ lams_ ["M","$M","A","m"] ("$M" @@ Quark "fmap" @@ "A" @@@ Unit @@ lam_ "_" (Inf I) @@ "m")
example_ $ apps_ "void" ["Identity", "MonadIdentity", forall_ "X" ("X" ~> "X"), lams_ ["X","x"] "x"]
defineInf_ "env" (hadron_ ["foo", "bar"])
example_ $ apps_ "void" ["Reader" @@ "env", "MonadReader" @@ "env", "env", lam_ "e" "e"]
#endif