{-# LANGUAGE UndecidableInstances #-}

module Symparsec.Parser.Or where

import Symparsec.Parser
import TypeLevelShow.Doc
import GHC.TypeLits hiding ( ErrorMessage(..) )
import DeFun.Core
import Singleraeh.Tuple
import Singleraeh.Either
import Singleraeh.List

{- | Limited parser choice. Try left; if it fails, backtrack and try right.
     However, _the right choice must consume at least as much as the left
     choice._ If it doesn't, then even if the right parser succeeds, it
     will emit an error.

This behaviour is due to the parser runner not supporting backtracking. We can
emulate it by storing a record of the characters parsed so far, and "replaying"
these on the right parser if the left parser fails. If the right parser ends
before we finish replaying, we will have consumed extra characters that we can't
ask the runner to revert.

For example, @Literal "abcd" :<|>: Literal "ab"@ is bad. An input of @abcX@ will
trigger the consumption error.

I can't think of another way to implement this with the current parser design. I
think it's the best we have. A more complex parser design may permit changing
internal running state, so we could save and load state (this would permit a
@Try p@ parser). But that's scary. And you're better off designing your
type-level string schemas to permit non-backtracking parsing anyway...

Also problematic is that we never emit a left parser error, so errors can
degrade. Perhaps your string was one character off a successful left parse; but
if it fails, you won't see that error.
-}
infixl 3 :<|>:
type (:<|>:)
    :: PParser sl rl
    -> PParser sr rr
    -> PParser (OrS sl sr) (Either rl rr)
type family pl :<|>: pr where
    'PParser plCh plEnd s0l :<|>: 'PParser prCh prEnd s0r =
        Or' plCh plEnd s0l prCh prEnd s0r

type Or' plCh plEnd s0l prCh prEnd s0r = 'PParser
    (OrChSym plCh prCh s0r)
    (OrEndSym plEnd prCh prEnd s0r)
    (Left '(s0l, '[]))

type SOrS ssl ssr = SEither (STuple2 ssl (SList SChar)) ssr
type OrS  sl  sr  = Either (sl, [Char]) sr
type SPOr ssl srl ssr srr plCh plEnd s0l prCh prEnd s0r =
    SParser (SOrS ssl ssr) (SEither srl srr) (Or' plCh plEnd s0l prCh prEnd s0r)

sOr
    :: SParser ssl srl ('PParser plCh plEnd s0l)
    -> SParser ssr srr ('PParser prCh prEnd s0r)
    -> SPOr    ssl srl ssr srr plCh plEnd s0l prCh prEnd s0r
sOr :: forall {a} {l} {r} {r} (ssl :: a -> Type) (srl :: l -> Type)
       (plCh :: ParserChSym a l) (plEnd :: ParserEndSym a l) (s0l :: a)
       (ssr :: r -> Type) (srr :: r -> Type) (prCh :: ParserChSym r r)
       (prEnd :: ParserEndSym r r) (s0r :: r).
SParser ssl srl ('PParser plCh plEnd s0l)
-> SParser ssr srr ('PParser prCh prEnd s0r)
-> SPOr ssl srl ssr srr plCh plEnd s0l prCh prEnd s0r
sOr (SParser SParserChSym ssl srl pCh
plCh SParserEndSym ssl srl pEnd
plEnd ssl s0
s0l) (SParser SParserChSym ssr srr pCh
prCh SParserEndSym ssr srr pEnd
prEnd ssr s0
s0r) = SParserChSym
  (SOrS ssl ssr) (SEither srl srr) (OrChSym plCh prCh s0r)
-> SParserEndSym
     (SOrS ssl ssr) (SEither srl srr) (OrEndSym plEnd prCh prEnd s0r)
-> SOrS ssl ssr ('Left '(s0l, '[]))
-> SParser
     (SOrS ssl ssr)
     (SEither srl srr)
     ('PParser
        (OrChSym plCh prCh s0r)
        (OrEndSym plEnd prCh prEnd s0r)
        ('Left '(s0l, '[])))
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 ssl srl plCh
-> SParserChSym ssr srr prCh
-> ssr s0r
-> SParserChSym
     (SOrS ssl ssr) (SEither srl srr) (OrChSym plCh prCh s0r)
forall {sl} {rl} {sr} {rr} (ssl :: sl -> Type) (srl :: rl -> Type)
       (plCh :: Char ~> (sl ~> PResult sl rl)) (ssr :: sr -> Type)
       (srr :: rr -> Type) (prCh :: Char ~> (sr ~> PResult sr rr))
       (s0r :: sr).
SParserChSym ssl srl plCh
-> SParserChSym ssr srr prCh
-> ssr s0r
-> SParserChSym
     (SOrS ssl ssr) (SEither srl srr) (OrChSym plCh prCh s0r)
sOrChSym SParserChSym ssl srl plCh
SParserChSym ssl srl pCh
plCh SParserChSym ssr srr prCh
SParserChSym ssr srr pCh
prCh ssr s0r
ssr s0
s0r)
    (SParserEndSym ssl srl plEnd
-> SParserChSym ssr srr prCh
-> SParserEndSym ssr srr prEnd
-> ssr s0r
-> SParserEndSym
     (SOrS ssl ssr) (SEither srl srr) (OrEndSym plEnd prCh prEnd s0r)
forall {sl} {rl} {sr} {rr} (ssl :: sl -> Type) (srl :: rl -> Type)
       (plEnd :: sl ~> Either PE rl) (ssr :: sr -> Type)
       (srr :: rr -> Type) (prCh :: Char ~> (sr ~> PResult sr rr))
       (prEnd :: sr ~> Either PE rr) (s0r :: sr).
SParserEndSym ssl srl plEnd
-> SParserChSym ssr srr prCh
-> SParserEndSym ssr srr prEnd
-> ssr s0r
-> SParserEndSym
     (SOrS ssl ssr) (SEither srl srr) (OrEndSym plEnd prCh prEnd s0r)
sOrEndSym SParserEndSym ssl srl plEnd
SParserEndSym ssl srl pEnd
plEnd SParserChSym ssr srr prCh
SParserChSym ssr srr pCh
prCh SParserEndSym ssr srr prEnd
SParserEndSym ssr srr pEnd
prEnd ssr s0r
ssr s0
s0r)
    (STuple2 ssl (SList SChar) '(s0l, '[])
-> SOrS ssl ssr ('Left '(s0l, '[]))
forall {l} {r} (sl :: l -> Type) (l1 :: l) (sr :: r -> Type).
sl l1 -> SEither sl sr ('Left l1)
SLeft (ssl s0l -> SList SChar '[] -> STuple2 ssl (SList SChar) '(s0l, '[])
forall {a} {b} (sa :: a -> Type) (a1 :: a) (sb :: b -> Type)
       (b1 :: b).
sa a1 -> sb b1 -> STuple2 sa sb '(a1, b1)
STuple2 ssl s0l
ssl s0
s0l SList SChar '[]
forall {a} (sa :: a -> Type). SList sa '[]
SNil))

instance
  ( pl ~ 'PParser plCh plEnd s0l
  , pr ~ 'PParser prCh prEnd s0r
  , SingParser pl
  , SingParser pr
  ) => SingParser (Or' plCh plEnd s0l prCh prEnd s0r) where
    type PS (Or' plCh plEnd s0l prCh prEnd s0r) = SOrS
        (PS ('PParser plCh plEnd s0l))
        (PS ('PParser prCh prEnd s0r))
    type PR (Or' plCh plEnd s0l prCh prEnd s0r) = SEither
        (PR ('PParser plCh plEnd s0l))
        (PR ('PParser prCh prEnd s0r))
    singParser' :: SParser
  (PS (Or' plCh plEnd s0l prCh prEnd s0r))
  (PR (Or' plCh plEnd s0l prCh prEnd s0r))
  (Or' plCh plEnd s0l prCh prEnd s0r)
singParser' = SParser
  (PS ('PParser plCh plEnd s0l))
  (PR ('PParser plCh plEnd s0l))
  ('PParser plCh plEnd s0l)
-> SParser
     (PS ('PParser prCh prEnd s0r))
     (PR ('PParser prCh prEnd s0r))
     ('PParser prCh prEnd s0r)
-> SPOr
     (PS ('PParser plCh plEnd s0l))
     (PR ('PParser plCh plEnd s0l))
     (PS ('PParser prCh prEnd s0r))
     (PR ('PParser prCh prEnd s0r))
     plCh
     plEnd
     s0l
     prCh
     prEnd
     s0r
forall {a} {l} {r} {r} (ssl :: a -> Type) (srl :: l -> Type)
       (plCh :: ParserChSym a l) (plEnd :: ParserEndSym a l) (s0l :: a)
       (ssr :: r -> Type) (srr :: r -> Type) (prCh :: ParserChSym r r)
       (prEnd :: ParserEndSym r r) (s0r :: r).
SParser ssl srl ('PParser plCh plEnd s0l)
-> SParser ssr srr ('PParser prCh prEnd s0r)
-> SPOr ssl srl ssr srr plCh plEnd s0l prCh prEnd s0r
sOr (forall {s} {r} (p :: PParser s r).
SingParser p =>
SParser (PS p) (PR p) p
forall (p :: PParser sl rl).
SingParser p =>
SParser (PS p) (PR p) p
singParser @pl) (forall {s} {r} (p :: PParser s r).
SingParser p =>
SParser (PS p) (PR p) p
forall (p :: PParser sr rr).
SingParser p =>
SParser (PS p) (PR p) p
singParser @pr)

type OrCh
    :: ParserChSym sl rl
    -> ParserChSym sr rr
    -> sr
    -> PParserCh (OrS sl sr) (Either rl rr)
type family OrCh plCh prCh sr ch s where
    -- | parsing left
    OrCh plCh prCh s0r ch (Left  '(sl, chs)) =
        OrChL prCh s0r ch chs (plCh @@ ch @@ sl)

    -- | parsing right (after left failed and was successfully replayed)
    OrCh plCh prCh _  ch (Right sr) =
        OrChR (prCh @@ ch @@ sr)

type OrChL
    :: ParserChSym sr rr
    -> sr
    -> Char
    -> [Char]
    -> PResult sl rl
    -> PResult (Either (sl, [Char]) sr) (Either rl rr)
type family OrChL prCh s0r chLast chs resl where
    -- | left parser OK, continue
    OrChL _    _   chLast chs (Cont sl) = Cont (Left  '(sl, chLast : chs))

    -- | left parser OK, done
    OrChL _    _   _      _   (Done rl) = Done (Left  rl)

    -- | left parser failed: ignore, replay consumed characters on right parser
    OrChL prCh s0r chLast chs (Err  _ ) =
        OrChLReplay prCh chLast (Reverse chs) (Cont s0r)

type OrChLReplay
    :: ParserChSym sr rr
    -> Char
    -> [Char]
    -> PResult sr rr
    -> PResult (Either (sl, [Char]) sr) (Either rl rr)
type family OrChLReplay prCh chLast chs resr where
    -- | right parser OK, keep replaying
    OrChLReplay prCh chLast (ch : chs) (Cont sr) =
        OrChLReplay prCh chLast chs (prCh @@ ch @@ sr)
    --
    -- | right parser OK, final replay char
    OrChLReplay prCh chLast '[]        (Cont sr) = OrChR (prCh @@ chLast @@ sr)

    -- | right parser fail: wrap error
    OrChLReplay prCh chLast chs        (Err  er) = Err (EOrR er)

    -- | right parser done but still replaying! no choice but to error out
    OrChLReplay prCh chLast chs        (Done rr) = Err EOrStillReplaying
        -- Done (Right rr) -- TODO

sOrChLReplay
    :: SParserChSym ssr srr prCh
    -> SChar chLast
    -> SList SChar chs
    -> SResult ssr srr resr
    -> SResult (SOrS ssl ssr) (SEither srl srr)
        (OrChLReplay prCh chLast chs resr)
sOrChLReplay :: forall {sr} {rr} {a} {l} (ssr :: sr -> Type) (srr :: rr -> Type)
       (prCh :: Char ~> (sr ~> PResult sr rr)) (chLast :: Char)
       (chs :: [Char]) (resr :: PResult sr rr) (ssl :: a -> Type)
       (srl :: l -> Type).
SParserChSym ssr srr prCh
-> SChar chLast
-> SList SChar chs
-> SResult ssr srr resr
-> SResult
     (SOrS ssl ssr) (SEither srl srr) (OrChLReplay prCh chLast chs resr)
sOrChLReplay SParserChSym ssr srr prCh
prCh SChar chLast
chLast SList SChar chs
chs SResult ssr srr resr
resr =
    case SList SChar chs
chs of
      SCons SChar a1
ch SList SChar as1
chs' ->
        case SResult ssr srr resr
resr of
          SCont  ssr s1
sr ->
            SParserChSym ssr srr prCh
-> SChar chLast
-> SList SChar as1
-> SResult ssr srr (App (App prCh a1) s1)
-> SResult
     (SOrS ssl ssr)
     (SEither srl srr)
     (OrChLReplay prCh chLast as1 (App (App prCh a1) s1))
forall {sr} {rr} {a} {l} (ssr :: sr -> Type) (srr :: rr -> Type)
       (prCh :: Char ~> (sr ~> PResult sr rr)) (chLast :: Char)
       (chs :: [Char]) (resr :: PResult sr rr) (ssl :: a -> Type)
       (srl :: l -> Type).
SParserChSym ssr srr prCh
-> SChar chLast
-> SList SChar chs
-> SResult ssr srr resr
-> SResult
     (SOrS ssl ssr) (SEither srl srr) (OrChLReplay prCh chLast chs resr)
sOrChLReplay SParserChSym ssr srr prCh
prCh SChar chLast
chLast SList SChar as1
chs' (SParserChSym ssr srr prCh
prCh SParserChSym ssr srr prCh
-> SChar a1 -> Lam ssr (SResult ssr srr) (App prCh a1)
forall {a1} {k} (a2 :: a1 -> Type) (b :: k -> Type) (f :: a1 ~> k)
       (x :: a1).
Lam a2 b f -> a2 x -> b (f @@ x)
@@ SChar a1
ch Lam ssr (SResult ssr srr) (App prCh a1)
-> ssr s1 -> SResult ssr srr (App (App prCh a1) s1)
forall {a1} {k} (a2 :: a1 -> Type) (b :: k -> Type) (f :: a1 ~> k)
       (x :: a1).
Lam a2 b f -> a2 x -> b (f @@ x)
@@ ssr s1
sr)
          SDone srr r1
_rr -> SE EOrStillReplaying
-> SResult
     (SOrS ssl ssr) (SEither srl srr) ('Err EOrStillReplaying)
forall {s} {r} (e :: PE) (ss :: s -> Type) (sr :: r -> Type).
SE e -> SResult ss sr ('Err e)
SErr SE EOrStillReplaying
eOrStillReplaying
          SErr   SE e
er -> SE (EOrR e)
-> SResult (SOrS ssl ssr) (SEither srl srr) ('Err (EOrR e))
forall {s} {r} (e :: PE) (ss :: s -> Type) (sr :: r -> Type).
SE e -> SResult ss sr ('Err e)
SErr (SE (EOrR e)
 -> SResult (SOrS ssl ssr) (SEither srl srr) ('Err (EOrR e)))
-> SE (EOrR e)
-> SResult (SOrS ssl ssr) (SEither srl srr) ('Err (EOrR e))
forall a b. (a -> b) -> a -> b
$ SE e -> SE (EOrR e)
forall (er :: PE). SE er -> SE (EOrR er)
eOrR SE e
er
      SList SChar chs
SNil ->
        case SResult ssr srr resr
resr of
          SCont  ssr s1
sr -> SResult ssr srr (App (App prCh chLast) s1)
-> SResult
     (SOrS ssl ssr) (SEither srl srr) (OrChR (App (App prCh chLast) s1))
forall {b} {b} {a} {l} (ssr :: b -> Type) (srr :: b -> Type)
       (resr :: PResult b b) (ssl :: a -> Type) (srl :: l -> Type).
SResult ssr srr resr
-> SResult (SOrS ssl ssr) (SEither srl srr) (OrChR resr)
sOrChR (SParserChSym ssr srr prCh
prCh SParserChSym ssr srr prCh
-> SChar chLast -> Lam ssr (SResult ssr srr) (App prCh chLast)
forall {a1} {k} (a2 :: a1 -> Type) (b :: k -> Type) (f :: a1 ~> k)
       (x :: a1).
Lam a2 b f -> a2 x -> b (f @@ x)
@@ SChar chLast
chLast Lam ssr (SResult ssr srr) (App prCh chLast)
-> ssr s1 -> SResult ssr srr (App (App prCh chLast) s1)
forall {a1} {k} (a2 :: a1 -> Type) (b :: k -> Type) (f :: a1 ~> k)
       (x :: a1).
Lam a2 b f -> a2 x -> b (f @@ x)
@@ ssr s1
sr)
          SDone srr r1
_rr -> SE EOrStillReplaying
-> SResult
     (SOrS ssl ssr) (SEither srl srr) ('Err EOrStillReplaying)
forall {s} {r} (e :: PE) (ss :: s -> Type) (sr :: r -> Type).
SE e -> SResult ss sr ('Err e)
SErr SE EOrStillReplaying
eOrStillReplaying
          SErr   SE e
er -> SE (EOrR e)
-> SResult (SOrS ssl ssr) (SEither srl srr) ('Err (EOrR e))
forall {s} {r} (e :: PE) (ss :: s -> Type) (sr :: r -> Type).
SE e -> SResult ss sr ('Err e)
SErr (SE (EOrR e)
 -> SResult (SOrS ssl ssr) (SEither srl srr) ('Err (EOrR e)))
-> SE (EOrR e)
-> SResult (SOrS ssl ssr) (SEither srl srr) ('Err (EOrR e))
forall a b. (a -> b) -> a -> b
$ SE e -> SE (EOrR e)
forall (er :: PE). SE er -> SE (EOrR er)
eOrR SE e
er

type EOrR er = EIn "Or(R)" er
eOrR :: SE er -> SE (EOrR er)
eOrR :: forall (er :: PE). SE er -> SE (EOrR er)
eOrR SE er
er = SSymbol "Or(R)" -> SE er -> SE ('EIn "Or(R)" er)
forall (name :: Symbol) (e1 :: PE).
SSymbol name -> SE e1 -> SE ('EIn name e1)
SEIn SSymbol "Or(R)"
forall (n :: Symbol). KnownSymbol n => SSymbol n
symbolSing SE er
er

type EOrStillReplaying = EBase "Or"
    (Text "right parser much consume at least as much as the failed left parser")
eOrStillReplaying :: SE EOrStillReplaying
eOrStillReplaying :: SE EOrStillReplaying
eOrStillReplaying = SE EOrStillReplaying
forall (e :: PE). SingE e => SE e
singE

type family OrChR resr where
    OrChR (Cont sr) = Cont (Right sr)
    OrChR (Done rr) = Done (Right rr)
    OrChR (Err  er) = Err (EOrR er)

sOrChR
    :: SResult ssr srr resr
    -> SResult (SOrS ssl ssr) (SEither srl srr) (OrChR resr)
sOrChR :: forall {b} {b} {a} {l} (ssr :: b -> Type) (srr :: b -> Type)
       (resr :: PResult b b) (ssl :: a -> Type) (srl :: l -> Type).
SResult ssr srr resr
-> SResult (SOrS ssl ssr) (SEither srl srr) (OrChR resr)
sOrChR = \case
  SCont ssr s1
sr -> SOrS ssl ssr ('Right s1)
-> SResult (SOrS ssl ssr) (SEither srl srr) ('Cont ('Right s1))
forall {s} {r} (ss :: s -> Type) (s1 :: s) (sr :: r -> Type).
ss s1 -> SResult ss sr ('Cont s1)
SCont (SOrS ssl ssr ('Right s1)
 -> SResult (SOrS ssl ssr) (SEither srl srr) ('Cont ('Right s1)))
-> SOrS ssl ssr ('Right s1)
-> SResult (SOrS ssl ssr) (SEither srl srr) ('Cont ('Right s1))
forall a b. (a -> b) -> a -> b
$ ssr s1 -> SOrS ssl ssr ('Right s1)
forall {r} {l} (sr :: r -> Type) (r1 :: r) (sl :: l -> Type).
sr r1 -> SEither sl sr ('Right r1)
SRight ssr s1
sr
  SDone srr r1
rr -> SEither srl srr ('Right r1)
-> SResult (SOrS ssl ssr) (SEither srl srr) ('Done ('Right r1))
forall {r} {s} (sr :: r -> Type) (r1 :: r) (ss :: s -> Type).
sr r1 -> SResult ss sr ('Done r1)
SDone (SEither srl srr ('Right r1)
 -> SResult (SOrS ssl ssr) (SEither srl srr) ('Done ('Right r1)))
-> SEither srl srr ('Right r1)
-> SResult (SOrS ssl ssr) (SEither srl srr) ('Done ('Right r1))
forall a b. (a -> b) -> a -> b
$ srr r1 -> SEither srl srr ('Right r1)
forall {r} {l} (sr :: r -> Type) (r1 :: r) (sl :: l -> Type).
sr r1 -> SEither sl sr ('Right r1)
SRight srr r1
rr
  SErr  SE e
er -> SE (EOrR e)
-> SResult (SOrS ssl ssr) (SEither srl srr) ('Err (EOrR e))
forall {s} {r} (e :: PE) (ss :: s -> Type) (sr :: r -> Type).
SE e -> SResult ss sr ('Err e)
SErr  (SE (EOrR e)
 -> SResult (SOrS ssl ssr) (SEither srl srr) ('Err (EOrR e)))
-> SE (EOrR e)
-> SResult (SOrS ssl ssr) (SEither srl srr) ('Err (EOrR e))
forall a b. (a -> b) -> a -> b
$ SE e -> SE (EOrR e)
forall (er :: PE). SE er -> SE (EOrR er)
eOrR SE e
er

type OrEnd
    :: ParserEndSym sl rl
    -> ParserChSym  sr rr
    -> ParserEndSym sr rr
    -> sr
    -> PParserEnd (Either (sl, [Char]) sr) (Either rl rr)
type family OrEnd plEnd prCh prEnd sr res where
    -- | input ended during left parser
    OrEnd plEnd prCh prEnd s0r (Left  '(sl, chs)) =
        OrEndL prCh prEnd s0r chs (plEnd @@ sl)

    -- | input ended during right parser: call right end
    OrEnd plEnd prCh prEnd _   (Right sr)         = OrEndR (prEnd @@ sr)

type OrEndR :: PResultEnd rr -> PResultEnd (Either rl rr)
type family OrEndR resr where
    OrEndR (Right rr) = Right (Right rr)
    OrEndR (Left  er) = Left  (EOrR er)

sOrEndR
    :: SResultEnd srr resr
    -> SResultEnd (SEither srl srr) (OrEndR resr)
sOrEndR :: forall {rr} {l} (srr :: rr -> Type) (resr :: Either PE rr)
       (srl :: l -> Type).
SResultEnd srr resr -> SResultEnd (SEither srl srr) (OrEndR resr)
sOrEndR = \case
  SRight srr r1
rr -> SEither srl srr ('Right r1)
-> SEither SE (SEither srl srr) ('Right ('Right r1))
forall {r} {l} (sr :: r -> Type) (r1 :: r) (sl :: l -> Type).
sr r1 -> SEither sl sr ('Right r1)
SRight (SEither srl srr ('Right r1)
 -> SEither SE (SEither srl srr) ('Right ('Right r1)))
-> SEither srl srr ('Right r1)
-> SEither SE (SEither srl srr) ('Right ('Right r1))
forall a b. (a -> b) -> a -> b
$ srr r1 -> SEither srl srr ('Right r1)
forall {r} {l} (sr :: r -> Type) (r1 :: r) (sl :: l -> Type).
sr r1 -> SEither sl sr ('Right r1)
SRight srr r1
rr
  SLeft  SE l1
er -> SE (EOrR l1) -> SEither SE (SEither srl srr) ('Left (EOrR l1))
forall {l} {r} (sl :: l -> Type) (l1 :: l) (sr :: r -> Type).
sl l1 -> SEither sl sr ('Left l1)
SLeft  (SE (EOrR l1) -> SEither SE (SEither srl srr) ('Left (EOrR l1)))
-> SE (EOrR l1) -> SEither SE (SEither srl srr) ('Left (EOrR l1))
forall a b. (a -> b) -> a -> b
$ SE l1 -> SE (EOrR l1)
forall (er :: PE). SE er -> SE (EOrR er)
eOrR SE l1
er

type OrEndL
    :: ParserChSym  sr rr
    -> ParserEndSym sr rr
    -> sr
    -> [Char]
    -> Either PE rl
    -> Either PE (Either rl rr)
type family OrEndL prCh prEnd s0r chs resl where
    -- | input ended during left parser and left end succeeeded: phew
    OrEndL prCh prEnd s0r chs (Right rl) = Right (Left rl)

    -- | input ended during left parser and left end failed. replay on right,
    --   then eventually call right end
    OrEndL prCh prEnd s0r chs (Left  el) =
        OrEndLReplay prCh prEnd (Reverse chs) (Cont s0r)

sOrEndL
    :: SParserChSym  ssr srr prCh
    -> SParserEndSym ssr srr prEnd
    -> ssr s0r
    -> SList SChar chs
    -> SResultEnd srl resl
    -> SResultEnd (SEither srl srr) (OrEndL prCh prEnd s0r chs resl)
sOrEndL :: forall {sr} {rr} {rl} (ssr :: sr -> Type) (srr :: rr -> Type)
       (prCh :: Char ~> (sr ~> PResult sr rr))
       (prEnd :: sr ~> Either PE rr) (s0r :: sr) (chs :: [Char])
       (srl :: rl -> Type) (resl :: Either PE rl).
SParserChSym ssr srr prCh
-> SParserEndSym ssr srr prEnd
-> ssr s0r
-> SList SChar chs
-> SResultEnd srl resl
-> SResultEnd (SEither srl srr) (OrEndL prCh prEnd s0r chs resl)
sOrEndL SParserChSym ssr srr prCh
prCh SParserEndSym ssr srr prEnd
prEnd ssr s0r
s0r SList SChar chs
chs = \case
  SRight  srl r1
rl -> SEither srl srr ('Left r1)
-> SEither SE (SEither srl srr) ('Right ('Left r1))
forall {r} {l} (sr :: r -> Type) (r1 :: r) (sl :: l -> Type).
sr r1 -> SEither sl sr ('Right r1)
SRight (SEither srl srr ('Left r1)
 -> SEither SE (SEither srl srr) ('Right ('Left r1)))
-> SEither srl srr ('Left r1)
-> SEither SE (SEither srl srr) ('Right ('Left r1))
forall a b. (a -> b) -> a -> b
$ srl r1 -> SEither srl srr ('Left r1)
forall {l} {r} (sl :: l -> Type) (l1 :: l) (sr :: r -> Type).
sl l1 -> SEither sl sr ('Left l1)
SLeft srl r1
rl
  SLeft  SE l1
_el -> SParserChSym ssr srr prCh
-> SParserEndSym ssr srr prEnd
-> SList SChar (Reverse' '[] chs)
-> SResult ssr srr ('Cont s0r)
-> SResultEnd
     (SEither srl srr)
     (OrEndLReplay prCh prEnd (Reverse' '[] chs) ('Cont s0r))
forall {sr} {rr} {l} (ssr :: sr -> Type) (srr :: rr -> Type)
       (prCh :: Char ~> (sr ~> PResult sr rr))
       (prEnd :: sr ~> Either PE rr) (chs :: [Char])
       (resr :: PResult sr rr) (srl :: l -> Type).
SParserChSym ssr srr prCh
-> SParserEndSym ssr srr prEnd
-> SList SChar chs
-> SResult ssr srr resr
-> SResultEnd (SEither srl srr) (OrEndLReplay prCh prEnd chs resr)
sOrEndLReplay SParserChSym ssr srr prCh
prCh SParserEndSym ssr srr prEnd
prEnd (SList SChar chs -> SList SChar (Reverse' '[] chs)
forall {k} (sa :: k -> Type) (as :: [k]).
SList sa as -> SList sa (Reverse as)
sReverse SList SChar chs
chs) (ssr s0r -> SResult ssr srr ('Cont s0r)
forall {s} {r} (ss :: s -> Type) (s1 :: s) (sr :: r -> Type).
ss s1 -> SResult ss sr ('Cont s1)
SCont ssr s0r
s0r)

type OrEndLReplay
    :: ParserChSym  sr rr
    -> ParserEndSym sr rr
    -> [Char]
    -> PResult sr rr
    -> Either PE (Either rl rr)
type family OrEndLReplay prCh prEnd chs resr where
    -- | right parser OK, keep replaying
    OrEndLReplay prCh prEnd (ch : chs) (Cont sr) =
        OrEndLReplay prCh prEnd chs (prCh @@ ch @@ sr)

    -- | replay complete
    OrEndLReplay prCh prEnd '[]        resr      = OrEndLReplay' prEnd resr

    -- | right parser fail: wrap error
    OrEndLReplay prCh prEnd chs        (Err  er) = Left (EOrR er)

    -- | right parser done but still replaying! no choice but to error out
    OrEndLReplay prCh prEnd chs        (Done rr) = Left EOrStillReplaying
        -- Right (Right rr) TODO

sOrEndLReplay
    :: SParserChSym  ssr srr prCh
    -> SParserEndSym ssr srr prEnd
    -> SList SChar chs
    -> SResult ssr srr resr
    -> SResultEnd (SEither srl srr) (OrEndLReplay prCh prEnd chs resr)
sOrEndLReplay :: forall {sr} {rr} {l} (ssr :: sr -> Type) (srr :: rr -> Type)
       (prCh :: Char ~> (sr ~> PResult sr rr))
       (prEnd :: sr ~> Either PE rr) (chs :: [Char])
       (resr :: PResult sr rr) (srl :: l -> Type).
SParserChSym ssr srr prCh
-> SParserEndSym ssr srr prEnd
-> SList SChar chs
-> SResult ssr srr resr
-> SResultEnd (SEither srl srr) (OrEndLReplay prCh prEnd chs resr)
sOrEndLReplay SParserChSym ssr srr prCh
prCh SParserEndSym ssr srr prEnd
prEnd SList SChar chs
chs SResult ssr srr resr
resr =
    case SList SChar chs
chs of
      SCons SChar a1
ch SList SChar as1
chs' ->
        case SResult ssr srr resr
resr of
          SCont  ssr s1
sr ->
            SParserChSym ssr srr prCh
-> SParserEndSym ssr srr prEnd
-> SList SChar as1
-> SResult ssr srr (App (App prCh a1) s1)
-> SResultEnd
     (SEither srl srr)
     (OrEndLReplay prCh prEnd as1 (App (App prCh a1) s1))
forall {sr} {rr} {l} (ssr :: sr -> Type) (srr :: rr -> Type)
       (prCh :: Char ~> (sr ~> PResult sr rr))
       (prEnd :: sr ~> Either PE rr) (chs :: [Char])
       (resr :: PResult sr rr) (srl :: l -> Type).
SParserChSym ssr srr prCh
-> SParserEndSym ssr srr prEnd
-> SList SChar chs
-> SResult ssr srr resr
-> SResultEnd (SEither srl srr) (OrEndLReplay prCh prEnd chs resr)
sOrEndLReplay SParserChSym ssr srr prCh
prCh SParserEndSym ssr srr prEnd
prEnd SList SChar as1
chs' (SParserChSym ssr srr prCh
prCh SParserChSym ssr srr prCh
-> SChar a1 -> Lam ssr (SResult ssr srr) (App prCh a1)
forall {a1} {k} (a2 :: a1 -> Type) (b :: k -> Type) (f :: a1 ~> k)
       (x :: a1).
Lam a2 b f -> a2 x -> b (f @@ x)
@@ SChar a1
ch Lam ssr (SResult ssr srr) (App prCh a1)
-> ssr s1 -> SResult ssr srr (App (App prCh a1) s1)
forall {a1} {k} (a2 :: a1 -> Type) (b :: k -> Type) (f :: a1 ~> k)
       (x :: a1).
Lam a2 b f -> a2 x -> b (f @@ x)
@@ ssr s1
sr)
          SErr   SE e
er -> SE (EOrR e) -> SEither SE (SEither srl srr) ('Left (EOrR e))
forall {l} {r} (sl :: l -> Type) (l1 :: l) (sr :: r -> Type).
sl l1 -> SEither sl sr ('Left l1)
SLeft (SE (EOrR e) -> SEither SE (SEither srl srr) ('Left (EOrR e)))
-> SE (EOrR e) -> SEither SE (SEither srl srr) ('Left (EOrR e))
forall a b. (a -> b) -> a -> b
$ SE e -> SE (EOrR e)
forall (er :: PE). SE er -> SE (EOrR er)
eOrR SE e
er
          SDone srr r1
_rr -> SE EOrStillReplaying
-> SEither SE (SEither srl srr) ('Left EOrStillReplaying)
forall {l} {r} (sl :: l -> Type) (l1 :: l) (sr :: r -> Type).
sl l1 -> SEither sl sr ('Left l1)
SLeft SE EOrStillReplaying
eOrStillReplaying
      SList SChar chs
SNil ->
        case SResult ssr srr resr
resr of
          SCont ssr s1
sr -> SResultEnd srr (App prEnd s1)
-> SResultEnd (SEither srl srr) (OrEndR (App prEnd s1))
forall {rr} {l} (srr :: rr -> Type) (resr :: Either PE rr)
       (srl :: l -> Type).
SResultEnd srr resr -> SResultEnd (SEither srl srr) (OrEndR resr)
sOrEndR (SResultEnd srr (App prEnd s1)
 -> SResultEnd (SEither srl srr) (OrEndR (App prEnd s1)))
-> SResultEnd srr (App prEnd s1)
-> SResultEnd (SEither srl srr) (OrEndR (App prEnd s1))
forall a b. (a -> b) -> a -> b
$ SParserEndSym ssr srr prEnd
prEnd SParserEndSym ssr srr prEnd
-> ssr s1 -> SResultEnd srr (App prEnd s1)
forall {a1} {k} (a2 :: a1 -> Type) (b :: k -> Type) (f :: a1 ~> k)
       (x :: a1).
Lam a2 b f -> a2 x -> b (f @@ x)
@@ ssr s1
sr
          SDone srr r1
rr -> SEither srl srr ('Right r1)
-> SEither SE (SEither srl srr) ('Right ('Right r1))
forall {r} {l} (sr :: r -> Type) (r1 :: r) (sl :: l -> Type).
sr r1 -> SEither sl sr ('Right r1)
SRight  (SEither srl srr ('Right r1)
 -> SEither SE (SEither srl srr) ('Right ('Right r1)))
-> SEither srl srr ('Right r1)
-> SEither SE (SEither srl srr) ('Right ('Right r1))
forall a b. (a -> b) -> a -> b
$ srr r1 -> SEither srl srr ('Right r1)
forall {r} {l} (sr :: r -> Type) (r1 :: r) (sl :: l -> Type).
sr r1 -> SEither sl sr ('Right r1)
SRight srr r1
rr
          SErr  SE e
er -> SE (EOrR e) -> SEither SE (SEither srl srr) ('Left (EOrR e))
forall {l} {r} (sl :: l -> Type) (l1 :: l) (sr :: r -> Type).
sl l1 -> SEither sl sr ('Left l1)
SLeft   (SE (EOrR e) -> SEither SE (SEither srl srr) ('Left (EOrR e)))
-> SE (EOrR e) -> SEither SE (SEither srl srr) ('Left (EOrR e))
forall a b. (a -> b) -> a -> b
$ SE e -> SE (EOrR e)
forall (er :: PE). SE er -> SE (EOrR er)
eOrR SE e
er

type family OrEndLReplay' prEnd resr where
    OrEndLReplay' prEnd (Cont sr) = OrEndR (prEnd @@ sr)
    OrEndLReplay' prEnd (Done rr) = Right  (Right rr)
    OrEndLReplay' prEnd (Err  er) = Left   (EOrR er)

type OrChSym
    :: ParserChSym sl rl
    -> ParserChSym sr rr
    -> sr
    -> ParserChSym (OrS sl sr) (Either rl rr)
data OrChSym plCh prCh s0r f
type instance App (OrChSym plCh prCh s0r) f = OrChSym1 plCh prCh s0r f

type OrChSym1
    :: ParserChSym sl rl
    -> ParserChSym sr rr
    -> sr
    -> ParserChSym1 (OrS sl sr) (Either rl rr)
data OrChSym1 plCh prCh sr ch s
type instance App (OrChSym1 plCh prCh sr ch) s = OrCh plCh prCh sr ch s

sOrChSym
    :: SParserChSym ssl srl plCh
    -> SParserChSym ssr srr prCh
    -> ssr s0r
    -> SParserChSym (SOrS ssl ssr) (SEither srl srr) (OrChSym plCh prCh s0r)
sOrChSym :: forall {sl} {rl} {sr} {rr} (ssl :: sl -> Type) (srl :: rl -> Type)
       (plCh :: Char ~> (sl ~> PResult sl rl)) (ssr :: sr -> Type)
       (srr :: rr -> Type) (prCh :: Char ~> (sr ~> PResult sr rr))
       (s0r :: sr).
SParserChSym ssl srl plCh
-> SParserChSym ssr srr prCh
-> ssr s0r
-> SParserChSym
     (SOrS ssl ssr) (SEither srl srr) (OrChSym plCh prCh s0r)
sOrChSym SParserChSym ssl srl plCh
plCh SParserChSym ssr srr prCh
prCh ssr s0r
s0r = LamRep2
  SChar
  (SOrS ssl ssr)
  (SResult (SOrS ssl ssr) (SEither srl srr))
  (OrChSym plCh prCh s0r)
-> Lam2
     SChar
     (SOrS ssl ssr)
     (SResult (SOrS ssl ssr) (SEither srl srr))
     (OrChSym plCh prCh s0r)
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
   (SOrS ssl ssr)
   (SResult (SOrS ssl ssr) (SEither srl srr))
   (OrChSym plCh prCh s0r)
 -> Lam2
      SChar
      (SOrS ssl ssr)
      (SResult (SOrS ssl ssr) (SEither srl srr))
      (OrChSym plCh prCh s0r))
-> LamRep2
     SChar
     (SOrS ssl ssr)
     (SResult (SOrS ssl ssr) (SEither srl srr))
     (OrChSym plCh prCh s0r)
-> Lam2
     SChar
     (SOrS ssl ssr)
     (SResult (SOrS ssl ssr) (SEither srl srr))
     (OrChSym plCh prCh s0r)
forall a b. (a -> b) -> a -> b
$ \SChar x
ch -> \case
  SLeft  (STuple2 ssl a1
sl SList SChar b1
chs) -> SParserChSym ssr srr prCh
-> ssr s0r
-> SChar x
-> SList SChar b1
-> SResult ssl srl (App (App plCh x) a1)
-> SResult
     (SOrS ssl ssr)
     (SEither srl srr)
     (OrChL prCh s0r x b1 (App (App plCh x) a1))
forall {sr} {rr} {sl} {rl} (ssr :: sr -> Type) (srr :: rr -> Type)
       (prCh :: Char ~> (sr ~> PResult sr rr)) (s0r :: sr)
       (chLast :: Char) (chs :: [Char]) (ssl :: sl -> Type)
       (srl :: rl -> Type) (resl :: PResult sl rl).
SParserChSym ssr srr prCh
-> ssr s0r
-> SChar chLast
-> SList SChar chs
-> SResult ssl srl resl
-> SResult
     (SOrS ssl ssr) (SEither srl srr) (OrChL prCh s0r chLast chs resl)
sOrChL SParserChSym ssr srr prCh
prCh ssr s0r
s0r SChar x
ch SList SChar b1
chs (SParserChSym ssl srl plCh
plCh SParserChSym ssl srl plCh
-> SChar x -> Lam ssl (SResult ssl srl) (App plCh x)
forall {a1} {k} (a2 :: a1 -> Type) (b :: k -> Type) (f :: a1 ~> k)
       (x :: a1).
Lam a2 b f -> a2 x -> b (f @@ x)
@@ SChar x
ch Lam ssl (SResult ssl srl) (App plCh x)
-> ssl a1 -> SResult ssl srl (App (App plCh x) a1)
forall {a1} {k} (a2 :: a1 -> Type) (b :: k -> Type) (f :: a1 ~> k)
       (x :: a1).
Lam a2 b f -> a2 x -> b (f @@ x)
@@ ssl a1
sl)
  SRight ssr r1
sr -> SResult ssr srr (App (App prCh x) r1)
-> SResult
     (SOrS ssl ssr) (SEither srl srr) (OrChR (App (App prCh x) r1))
forall {b} {b} {a} {l} (ssr :: b -> Type) (srr :: b -> Type)
       (resr :: PResult b b) (ssl :: a -> Type) (srl :: l -> Type).
SResult ssr srr resr
-> SResult (SOrS ssl ssr) (SEither srl srr) (OrChR resr)
sOrChR (SParserChSym ssr srr prCh
prCh SParserChSym ssr srr prCh
-> SChar x -> Lam ssr (SResult ssr srr) (App prCh x)
forall {a1} {k} (a2 :: a1 -> Type) (b :: k -> Type) (f :: a1 ~> k)
       (x :: a1).
Lam a2 b f -> a2 x -> b (f @@ x)
@@ SChar x
ch Lam ssr (SResult ssr srr) (App prCh x)
-> ssr r1 -> SResult ssr srr (App (App prCh x) r1)
forall {a1} {k} (a2 :: a1 -> Type) (b :: k -> Type) (f :: a1 ~> k)
       (x :: a1).
Lam a2 b f -> a2 x -> b (f @@ x)
@@ ssr r1
sr)

sOrChL
    :: SParserChSym ssr srr prCh
    -> ssr s0r
    -> SChar chLast
    -> SList SChar chs
    -> SResult ssl srl resl
    -> SResult (SOrS ssl ssr) (SEither srl srr) (OrChL prCh s0r chLast chs resl)
sOrChL :: forall {sr} {rr} {sl} {rl} (ssr :: sr -> Type) (srr :: rr -> Type)
       (prCh :: Char ~> (sr ~> PResult sr rr)) (s0r :: sr)
       (chLast :: Char) (chs :: [Char]) (ssl :: sl -> Type)
       (srl :: rl -> Type) (resl :: PResult sl rl).
SParserChSym ssr srr prCh
-> ssr s0r
-> SChar chLast
-> SList SChar chs
-> SResult ssl srl resl
-> SResult
     (SOrS ssl ssr) (SEither srl srr) (OrChL prCh s0r chLast chs resl)
sOrChL SParserChSym ssr srr prCh
prCh ssr s0r
s0r SChar chLast
chLast SList SChar chs
chs = \case
  SCont  ssl s1
sl -> SOrS ssl ssr ('Left '(s1, chLast : chs))
-> SResult
     (SOrS ssl ssr)
     (SEither srl srr)
     ('Cont ('Left '(s1, chLast : chs)))
forall {s} {r} (ss :: s -> Type) (s1 :: s) (sr :: r -> Type).
ss s1 -> SResult ss sr ('Cont s1)
SCont (SOrS ssl ssr ('Left '(s1, chLast : chs))
 -> SResult
      (SOrS ssl ssr)
      (SEither srl srr)
      ('Cont ('Left '(s1, chLast : chs))))
-> SOrS ssl ssr ('Left '(s1, chLast : chs))
-> SResult
     (SOrS ssl ssr)
     (SEither srl srr)
     ('Cont ('Left '(s1, chLast : chs)))
forall a b. (a -> b) -> a -> b
$ STuple2 ssl (SList SChar) '(s1, chLast : chs)
-> SOrS ssl ssr ('Left '(s1, chLast : chs))
forall {l} {r} (sl :: l -> Type) (l1 :: l) (sr :: r -> Type).
sl l1 -> SEither sl sr ('Left l1)
SLeft (STuple2 ssl (SList SChar) '(s1, chLast : chs)
 -> SOrS ssl ssr ('Left '(s1, chLast : chs)))
-> STuple2 ssl (SList SChar) '(s1, chLast : chs)
-> SOrS ssl ssr ('Left '(s1, chLast : chs))
forall a b. (a -> b) -> a -> b
$ ssl s1
-> SList SChar (chLast : chs)
-> STuple2 ssl (SList SChar) '(s1, chLast : chs)
forall {a} {b} (sa :: a -> Type) (a1 :: a) (sb :: b -> Type)
       (b1 :: b).
sa a1 -> sb b1 -> STuple2 sa sb '(a1, b1)
STuple2 ssl s1
sl (SList SChar (chLast : chs)
 -> STuple2 ssl (SList SChar) '(s1, chLast : chs))
-> SList SChar (chLast : chs)
-> STuple2 ssl (SList SChar) '(s1, chLast : chs)
forall a b. (a -> b) -> a -> b
$ SChar chLast -> SList SChar chs -> SList SChar (chLast : chs)
forall {a} (sa :: a -> Type) (a1 :: a) (as1 :: [a]).
sa a1 -> SList sa as1 -> SList sa (a1 : as1)
SCons SChar chLast
chLast SList SChar chs
chs
  SDone  srl r1
rl -> SEither srl srr ('Left r1)
-> SResult (SOrS ssl ssr) (SEither srl srr) ('Done ('Left r1))
forall {r} {s} (sr :: r -> Type) (r1 :: r) (ss :: s -> Type).
sr r1 -> SResult ss sr ('Done r1)
SDone (SEither srl srr ('Left r1)
 -> SResult (SOrS ssl ssr) (SEither srl srr) ('Done ('Left r1)))
-> SEither srl srr ('Left r1)
-> SResult (SOrS ssl ssr) (SEither srl srr) ('Done ('Left r1))
forall a b. (a -> b) -> a -> b
$ srl r1 -> SEither srl srr ('Left r1)
forall {l} {r} (sl :: l -> Type) (l1 :: l) (sr :: r -> Type).
sl l1 -> SEither sl sr ('Left l1)
SLeft srl r1
rl
  SErr  SE e
_el -> SParserChSym ssr srr prCh
-> SChar chLast
-> SList SChar (Reverse' '[] chs)
-> SResult ssr srr ('Cont s0r)
-> SResult
     (SOrS ssl ssr)
     (SEither srl srr)
     (OrChLReplay prCh chLast (Reverse' '[] chs) ('Cont s0r))
forall {sr} {rr} {a} {l} (ssr :: sr -> Type) (srr :: rr -> Type)
       (prCh :: Char ~> (sr ~> PResult sr rr)) (chLast :: Char)
       (chs :: [Char]) (resr :: PResult sr rr) (ssl :: a -> Type)
       (srl :: l -> Type).
SParserChSym ssr srr prCh
-> SChar chLast
-> SList SChar chs
-> SResult ssr srr resr
-> SResult
     (SOrS ssl ssr) (SEither srl srr) (OrChLReplay prCh chLast chs resr)
sOrChLReplay SParserChSym ssr srr prCh
prCh SChar chLast
chLast (SList SChar chs -> SList SChar (Reverse' '[] chs)
forall {k} (sa :: k -> Type) (as :: [k]).
SList sa as -> SList sa (Reverse as)
sReverse SList SChar chs
chs) (ssr s0r -> SResult ssr srr ('Cont s0r)
forall {s} {r} (ss :: s -> Type) (s1 :: s) (sr :: r -> Type).
ss s1 -> SResult ss sr ('Cont s1)
SCont ssr s0r
s0r)

type OrEndSym
    :: ParserEndSym sl rl
    -> ParserChSym  sr rr
    -> ParserEndSym sr rr
    -> sr
    -> ParserEndSym (Either (sl, [Char]) sr) (Either rl rr)
data OrEndSym plEnd prCh prEnd s0r s
type instance App (OrEndSym plEnd prCh prEnd s0r) s =
    OrEnd plEnd prCh prEnd s0r s

sOrEndSym
    :: SParserEndSym ssl srl plEnd
    -> SParserChSym  ssr srr prCh
    -> SParserEndSym ssr srr prEnd
    -> ssr s0r
    -> SParserEndSym (SOrS ssl ssr) (SEither srl srr)
        (OrEndSym plEnd prCh prEnd s0r)
sOrEndSym :: forall {sl} {rl} {sr} {rr} (ssl :: sl -> Type) (srl :: rl -> Type)
       (plEnd :: sl ~> Either PE rl) (ssr :: sr -> Type)
       (srr :: rr -> Type) (prCh :: Char ~> (sr ~> PResult sr rr))
       (prEnd :: sr ~> Either PE rr) (s0r :: sr).
SParserEndSym ssl srl plEnd
-> SParserChSym ssr srr prCh
-> SParserEndSym ssr srr prEnd
-> ssr s0r
-> SParserEndSym
     (SOrS ssl ssr) (SEither srl srr) (OrEndSym plEnd prCh prEnd s0r)
sOrEndSym SParserEndSym ssl srl plEnd
plEnd SParserChSym ssr srr prCh
prCh SParserEndSym ssr srr prEnd
prEnd ssr s0r
s0r = LamRep
  (SOrS ssl ssr)
  (SResultEnd (SEither srl srr))
  (OrEndSym plEnd prCh prEnd s0r)
-> Lam
     (SOrS ssl ssr)
     (SResultEnd (SEither srl srr))
     (OrEndSym plEnd prCh prEnd s0r)
forall a b (a1 :: a -> Type) (b1 :: b -> Type) (f :: a ~> b).
LamRep a1 b1 f -> Lam a1 b1 f
Lam (LamRep
   (SOrS ssl ssr)
   (SResultEnd (SEither srl srr))
   (OrEndSym plEnd prCh prEnd s0r)
 -> Lam
      (SOrS ssl ssr)
      (SResultEnd (SEither srl srr))
      (OrEndSym plEnd prCh prEnd s0r))
-> LamRep
     (SOrS ssl ssr)
     (SResultEnd (SEither srl srr))
     (OrEndSym plEnd prCh prEnd s0r)
-> Lam
     (SOrS ssl ssr)
     (SResultEnd (SEither srl srr))
     (OrEndSym plEnd prCh prEnd s0r)
forall a b. (a -> b) -> a -> b
$ \case
  SLeft (STuple2 ssl a1
sl SList SChar b1
chs) -> SParserChSym ssr srr prCh
-> SParserEndSym ssr srr prEnd
-> ssr s0r
-> SList SChar b1
-> SResultEnd srl (App plEnd a1)
-> SResultEnd
     (SEither srl srr) (OrEndL prCh prEnd s0r b1 (App plEnd a1))
forall {sr} {rr} {rl} (ssr :: sr -> Type) (srr :: rr -> Type)
       (prCh :: Char ~> (sr ~> PResult sr rr))
       (prEnd :: sr ~> Either PE rr) (s0r :: sr) (chs :: [Char])
       (srl :: rl -> Type) (resl :: Either PE rl).
SParserChSym ssr srr prCh
-> SParserEndSym ssr srr prEnd
-> ssr s0r
-> SList SChar chs
-> SResultEnd srl resl
-> SResultEnd (SEither srl srr) (OrEndL prCh prEnd s0r chs resl)
sOrEndL SParserChSym ssr srr prCh
prCh SParserEndSym ssr srr prEnd
prEnd ssr s0r
s0r SList SChar b1
chs (SParserEndSym ssl srl plEnd
plEnd SParserEndSym ssl srl plEnd
-> ssl a1 -> SResultEnd srl (App plEnd a1)
forall {a1} {k} (a2 :: a1 -> Type) (b :: k -> Type) (f :: a1 ~> k)
       (x :: a1).
Lam a2 b f -> a2 x -> b (f @@ x)
@@ ssl a1
sl)
  SRight ssr r1
sr -> SResultEnd srr (App prEnd r1)
-> SResultEnd (SEither srl srr) (OrEndR (App prEnd r1))
forall {rr} {l} (srr :: rr -> Type) (resr :: Either PE rr)
       (srl :: l -> Type).
SResultEnd srr resr -> SResultEnd (SEither srl srr) (OrEndR resr)
sOrEndR (SResultEnd srr (App prEnd r1)
 -> SResultEnd (SEither srl srr) (OrEndR (App prEnd r1)))
-> SResultEnd srr (App prEnd r1)
-> SResultEnd (SEither srl srr) (OrEndR (App prEnd r1))
forall a b. (a -> b) -> a -> b
$ SParserEndSym ssr srr prEnd
prEnd SParserEndSym ssr srr prEnd
-> ssr r1 -> SResultEnd srr (App prEnd r1)
forall {a1} {k} (a2 :: a1 -> Type) (b :: k -> Type) (f :: a1 ~> k)
       (x :: a1).
Lam a2 b f -> a2 x -> b (f @@ x)
@@ ssr r1
sr