{-# LANGUAGE UndecidableInstances#-}
module Symparsec.Example.Expr where
import Numeric.Natural
import Symparsec.Parsers qualified as P
import Symparsec.Parser.While.Predicates qualified as P
import Symparsec.Parser.Apply qualified as P
import DeFun.Core
import DeFun.Function
data Expr
= ELit Lit
| EBOp Expr BOp Expr
data BOp = Plus
data Lit
= LNat Natural
type PLit = PLNat
type PLNat = Con1 LNat P.:<$>: P.While P.IsHexDigitSym P.NatHex
type PELit = Con1 ELit P.:<$>: PLit
type PEBOp = Curry3Sym (Con3 EBOp) P.:<$>: (PExpr P.:<*>: PBOp P.:<*>: PExpr)
type PExpr = PELit
type PBOp = ConstSym1 Plus P.:<$>: P.Literal "+"
type Curry3Sym
:: (a ~> b ~> c ~> r)
-> ((a, b), c)
~> r
data Curry3Sym f abc
type instance App (Curry3Sym f) '( '(a, b), c) = f @@ a @@ b @@ c
type FromEither :: Either a a -> a
type family FromEither eaa where
FromEither (Right a) = a
FromEither (Left a) = a
type FromEitherSym :: Either a a ~> a
data FromEitherSym eaa
type instance App FromEitherSym eaa = FromEither eaa