module Symparsec.Parser.End where

import Symparsec.Parser.Common
import DeFun.Core
import Singleraeh.Tuple ( SUnit(..) )
import Singleraeh.Either ( SEither(..) )

-- | Assert end of symbol, or fail.
type End :: PParser () ()
type End = 'PParser EndChSym (Con1 Right) '()

sEnd :: SParser SUnit SUnit End
sEnd :: SParser SUnit SUnit End
sEnd = SParserChSym SUnit SUnit EndChSym
-> SParserEndSym SUnit SUnit (Con1 'Right)
-> SUnit '()
-> SParser SUnit SUnit End
forall {s} {r} (ss :: s -> Type) (sr :: r -> Type)
       (pCh :: ParserChSym s r) (pEnd :: ParserEndSym s r) (s0 :: s).
SParserChSym ss sr pCh
-> SParserEndSym ss sr pEnd
-> ss s0
-> SParser ss sr ('PParser pCh pEnd s0)
SParser SParserChSym SUnit SUnit EndChSym
forall {s} {r} (ss :: s -> Type) (rr :: r -> Type).
SParserChSym ss rr EndChSym
sEndChSym (LamRep SUnit (SResultEnd SUnit) (Con1 'Right)
-> SParserEndSym SUnit SUnit (Con1 'Right)
forall {a1} {b1} (a2 :: a1 -> Type) (b2 :: b1 -> Type)
       (con :: a1 -> b1).
LamRep a2 b2 (Con1 con) -> Lam a2 b2 (Con1 con)
con1 SUnit x -> SEither SE SUnit ('Right x)
SUnit x -> SEither SE SUnit (App (Con1 'Right) x)
forall {r} {l} (sr :: r -> Type) (r1 :: r) (sl :: l -> Type).
sr r1 -> SEither sl sr ('Right r1)
LamRep SUnit (SResultEnd SUnit) (Con1 'Right)
SRight) SUnit '()
SUnit

instance SingParser End where
    type PS  End = SUnit
    type PR  End = SUnit
    singParser' :: SParser (PS End) (PR End) End
singParser' = SParser SUnit SUnit End
SParser (PS End) (PR End) End
sEnd

-- it'd be nice to just reuse FailChSym here but we get told off for writing an
-- orphan instance. fair enough, write this instead
type EndChSym :: ParserChSym s r
data EndChSym f
type instance App EndChSym f = EndChSym1 f

type EndChSym1 :: ParserChSym1 s r
data EndChSym1 ch s
type instance App (EndChSym1 ch) s =
    Err (EBase "End" (Text "expected end of string"))

sEndChSym :: SParserChSym ss rr EndChSym
sEndChSym :: forall {s} {r} (ss :: s -> Type) (rr :: r -> Type).
SParserChSym ss rr EndChSym
sEndChSym = LamRep2 SChar ss (SResult ss rr) EndChSym
-> Lam2 SChar ss (SResult ss rr) EndChSym
forall {a1} {a2} {b1} (a3 :: a1 -> Type) (b2 :: a2 -> Type)
       (c :: b1 -> Type) (fun :: a1 ~> (a2 ~> b1)).
LamRep2 a3 b2 c fun -> Lam2 a3 b2 c fun
Lam2 (LamRep2 SChar ss (SResult ss rr) EndChSym
 -> Lam2 SChar ss (SResult ss rr) EndChSym)
-> LamRep2 SChar ss (SResult ss rr) EndChSym
-> Lam2 SChar ss (SResult ss rr) EndChSym
forall a b. (a -> b) -> a -> b
$ \SChar x
_ch ss y
_s -> SE ('EBase "End" ('Text "expected end of string"))
-> SResult
     ss rr ('Err ('EBase "End" ('Text "expected end of string")))
forall {s} {r} (e :: PE) (ss :: s -> Type) (sr :: r -> Type).
SE e -> SResult ss sr ('Err e)
SErr SE ('EBase "End" ('Text "expected end of string"))
forall (e :: PE). SingE e => SE e
singE