{-|
Module:     Codec.Parser.Core
Copyright:  Jeremy List
License:    BSD-3
Maintainer: quick.dudley@gmail.com

Core functions and types.
-}
{-# LANGUAGE CPP, RankNTypes, MultiParamTypeClasses, FunctionalDependencies, ScopedTypeVariables #-}
module Codec.Phaser.Core (
  Automaton,
  Phase,
  get,
  put,
  put1,
  buffer,
  count,
  getCount,
  yield,
  eof,
  neof,
  (<?>),
  chainWith,
  (>>#),
  (>#>),
  starve,
  PhaserType(..),
  fitYield,
  fitGet,
  beforeStep,
  step,
  extract,
  toReadS,
  run,
  parse_,
  parse1_,
  options,
  readCount,
  outputs,
  stream
 ) where

import Control.Applicative
import Control.Monad
import Data.Void
import Unsafe.Coerce
#if MIN_VERSION_base(4,9,0)
import qualified Control.Monad.Fail as MF
#endif

-- | Represents a nondeterministic computation in progress.
-- There are 4 type parameters: a counter type (may be used for tracking line
-- and column numbers), an input type, an incremental output type, and a final
-- output type.
data Automaton p i o a =
  Result a |
  Ready (i -> Automaton p i o a) ([String] -> [String]) |
  Failed ([String] -> [String]) |
  Automaton p i o a :+++ Automaton p i o a |
  Yield o (Automaton p i o a) |
  Count p (Automaton p i o a) |
  GetCount (p -> Automaton p i o a)

-- | A type for building 'Automaton' values. 'Monad' and 'Applicative' instances
-- are defined for this type rather than for 'Automaton' in order to avoid
-- traversing the entire call stack for every input value.
newtype Phase p i o a =
  Phase (([String] -> [String]) ->
    forall b . (a -> Automaton p i o b) -> Automaton p i o b)

infixr 4 >>#
infixl 5 $#$
-- | Class for types which consume and produce incremental input and output.
class PhaserType s where
  toAutomaton :: (Monoid p) => s p i o a -> Automaton p i o a
  fromAutomaton :: (Monoid p) => Automaton p i o a -> s p i o a
  toPhase :: (Monoid p) => s p i o a -> Phase p i o a
  fromPhase :: (Monoid p) => Phase p i o a -> s p i o a
  ($#$) :: (Monoid p) => s p b c x -> (c -> t) -> s p b t x

instance Functor (Phase p i o) where
  fmap :: forall a b. (a -> b) -> Phase p i o a -> Phase p i o b
fmap a -> b
f (Phase ([String] -> [String])
-> forall b. (a -> Automaton p i o b) -> Automaton p i o b
x) = (([String] -> [String])
 -> forall b. (b -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o b
forall p i o a.
(([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
Phase (\[String] -> [String]
e b -> Automaton p i o b
c -> ([String] -> [String])
-> forall b. (a -> Automaton p i o b) -> Automaton p i o b
x [String] -> [String]
e (b -> Automaton p i o b
c (b -> Automaton p i o b) -> (a -> b) -> a -> Automaton p i o b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f))

instance Applicative (Phase p i o) where
  pure :: forall a. a -> Phase p i o a
pure a
a = (([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
forall p i o a.
(([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
Phase (\[String] -> [String]
e a -> Automaton p i o b
c -> a -> Automaton p i o b
c a
a)
  Phase ([String] -> [String])
-> forall b. ((a -> b) -> Automaton p i o b) -> Automaton p i o b
f <*> :: forall a b. Phase p i o (a -> b) -> Phase p i o a -> Phase p i o b
<*> Phase ([String] -> [String])
-> forall b. (a -> Automaton p i o b) -> Automaton p i o b
a = (([String] -> [String])
 -> forall b. (b -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o b
forall p i o a.
(([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
Phase (\[String] -> [String]
e b -> Automaton p i o b
c -> ([String] -> [String])
-> forall b. ((a -> b) -> Automaton p i o b) -> Automaton p i o b
f [String] -> [String]
e (\a -> b
f' -> ([String] -> [String])
-> forall b. (a -> Automaton p i o b) -> Automaton p i o b
a [String] -> [String]
e (b -> Automaton p i o b
c (b -> Automaton p i o b) -> (a -> b) -> a -> Automaton p i o b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f')))
  Phase ([String] -> [String])
-> forall b. (a -> Automaton p i o b) -> Automaton p i o b
a <* :: forall a b. Phase p i o a -> Phase p i o b -> Phase p i o a
<* Phase ([String] -> [String])
-> forall b. (b -> Automaton p i o b) -> Automaton p i o b
b = (([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
forall p i o a.
(([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
Phase (\[String] -> [String]
e a -> Automaton p i o b
c -> ([String] -> [String])
-> forall b. (a -> Automaton p i o b) -> Automaton p i o b
a [String] -> [String]
e (\a
a' -> ([String] -> [String])
-> forall b. (b -> Automaton p i o b) -> Automaton p i o b
b [String] -> [String]
e (Automaton p i o b -> b -> Automaton p i o b
forall a b. a -> b -> a
const (a -> Automaton p i o b
c a
a'))))
  Phase ([String] -> [String])
-> forall b. (a -> Automaton p i o b) -> Automaton p i o b
a *> :: forall a b. Phase p i o a -> Phase p i o b -> Phase p i o b
*> Phase ([String] -> [String])
-> forall b. (b -> Automaton p i o b) -> Automaton p i o b
b = (([String] -> [String])
 -> forall b. (b -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o b
forall p i o a.
(([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
Phase (\[String] -> [String]
e b -> Automaton p i o b
c -> ([String] -> [String])
-> forall b. (a -> Automaton p i o b) -> Automaton p i o b
a [String] -> [String]
e (Automaton p i o b -> a -> Automaton p i o b
forall a b. a -> b -> a
const (([String] -> [String])
-> forall b. (b -> Automaton p i o b) -> Automaton p i o b
b [String] -> [String]
e b -> Automaton p i o b
c)))

-- This is the first time I've ever created a separate '>>' method for a monad
-- instance, but turns out in this case it's a significant optimization.
instance Monad (Phase p i o) where
  return :: forall a. a -> Phase p i o a
return = a -> Phase p i o a
forall a. a -> Phase p i o a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
#if !(MIN_VERSION_base(4,13,0))
  fail s = Phase (\e _ -> Failed (e . (s:)))
#endif
  Phase ([String] -> [String])
-> forall b. (a -> Automaton p i o b) -> Automaton p i o b
a >>= :: forall a b. Phase p i o a -> (a -> Phase p i o b) -> Phase p i o b
>>= a -> Phase p i o b
f = (([String] -> [String])
 -> forall b. (b -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o b
forall p i o a.
(([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
Phase (\[String] -> [String]
e b -> Automaton p i o b
c -> ([String] -> [String])
-> forall b. (a -> Automaton p i o b) -> Automaton p i o b
a [String] -> [String]
e (\a
a' -> let Phase ([String] -> [String])
-> forall b. (b -> Automaton p i o b) -> Automaton p i o b
b = a -> Phase p i o b
f a
a' in ([String] -> [String])
-> forall b. (b -> Automaton p i o b) -> Automaton p i o b
b [String] -> [String]
e b -> Automaton p i o b
c))
  >> :: forall a b. Phase p i o a -> Phase p i o b -> Phase p i o b
(>>) = Phase p i o a -> Phase p i o b -> Phase p i o b
forall a b. Phase p i o a -> Phase p i o b -> Phase p i o b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
(*>)
  

#if MIN_VERSION_base(4,9,0)
instance MF.MonadFail (Phase p i o) where
  fail :: forall a. String -> Phase p i o a
fail String
s = (([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
forall p i o a.
(([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
Phase (\[String] -> [String]
e a -> Automaton p i o b
_ -> ([String] -> [String]) -> Automaton p i o b
forall p i o a. ([String] -> [String]) -> Automaton p i o a
Failed ([String] -> [String]
e ([String] -> [String])
-> ([String] -> [String]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String
sString -> [String] -> [String]
forall a. a -> [a] -> [a]
:)))
#endif

instance (Monoid p) => Alternative (Phase p i o) where
  empty :: forall a. Phase p i o a
empty = (([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
forall p i o a.
(([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
Phase (\[String] -> [String]
e a -> Automaton p i o b
_ -> ([String] -> [String]) -> Automaton p i o b
forall p i o a. ([String] -> [String]) -> Automaton p i o a
Failed [String] -> [String]
e)
  Phase ([String] -> [String])
-> forall b. (a -> Automaton p i o b) -> Automaton p i o b
a <|> :: forall a. Phase p i o a -> Phase p i o a -> Phase p i o a
<|> Phase ([String] -> [String])
-> forall b. (a -> Automaton p i o b) -> Automaton p i o b
b = (([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
forall p i o a.
(([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
Phase (\[String] -> [String]
e a -> Automaton p i o b
c -> Automaton p i o b -> Automaton p i o b
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (([String] -> [String])
-> forall b. (a -> Automaton p i o b) -> Automaton p i o b
a [String] -> [String]
e a -> Automaton p i o b
c Automaton p i o b -> Automaton p i o b -> Automaton p i o b
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ ([String] -> [String])
-> forall b. (a -> Automaton p i o b) -> Automaton p i o b
b [String] -> [String]
forall a. a -> a
id a -> Automaton p i o b
c))
  many :: forall a. Phase p i o a -> Phase p i o [a]
many Phase p i o a
a = Phase p i o a -> Phase p i o [a]
forall a. Phase p i o a -> Phase p i o [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
some Phase p i o a
a Phase p i o [a] -> Phase p i o [a] -> Phase p i o [a]
forall a. Phase p i o a -> Phase p i o a -> Phase p i o a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> [a] -> Phase p i o [a]
forall a. a -> Phase p i o a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
  some :: forall a. Phase p i o a -> Phase p i o [a]
some (Phase ([String] -> [String])
-> forall b. (a -> Automaton p i o b) -> Automaton p i o b
a) = (([String] -> [String])
 -> forall b. ([a] -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o [a]
forall p i o a.
(([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
Phase (\[String] -> [String]
e [a] -> Automaton p i o b
c -> let
    go :: ([a] -> [a]) -> Automaton p i o b
go [a] -> [a]
acc = ([String] -> [String])
-> forall b. (a -> Automaton p i o b) -> Automaton p i o b
a [String] -> [String]
e (\a
x -> let acc' :: [a] -> [a]
acc' = [a] -> [a]
acc ([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:) in Automaton p i o b -> Automaton p i o b
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (([a] -> [a]) -> Automaton p i o b
go [a] -> [a]
acc' Automaton p i o b -> Automaton p i o b -> Automaton p i o b
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ [a] -> Automaton p i o b
c ([a] -> [a]
acc' [])))
    in ([a] -> [a]) -> Automaton p i o b
go [a] -> [a]
forall a. a -> a
id
   )

instance (Monoid p) => MonadPlus (Phase p i o) where
  mzero :: forall a. Phase p i o a
mzero = Phase p i o a
forall a. Phase p i o a
forall (f :: * -> *) a. Alternative f => f a
empty
  mplus :: forall a. Phase p i o a -> Phase p i o a -> Phase p i o a
mplus = Phase p i o a -> Phase p i o a -> Phase p i o a
forall a. Phase p i o a -> Phase p i o a -> Phase p i o a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
(<|>)

instance Functor (Automaton p i o) where
  fmap :: forall a b. (a -> b) -> Automaton p i o a -> Automaton p i o b
fmap a -> b
f = Automaton p i o a -> Automaton p i o b
forall {p} {i} {o}. Automaton p i o a -> Automaton p i o b
go where
    go :: Automaton p i o a -> Automaton p i o b
go (Result a
a) = b -> Automaton p i o b
forall p i o a. a -> Automaton p i o a
Result (a -> b
f a
a)
    go (Ready i -> Automaton p i o a
n [String] -> [String]
e) = (i -> Automaton p i o b)
-> ([String] -> [String]) -> Automaton p i o b
forall p i o a.
(i -> Automaton p i o a)
-> ([String] -> [String]) -> Automaton p i o a
Ready ((Automaton p i o a -> Automaton p i o b)
-> (i -> Automaton p i o a) -> i -> Automaton p i o b
forall a b. (a -> b) -> (i -> a) -> i -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Automaton p i o a -> Automaton p i o b
go i -> Automaton p i o a
n) [String] -> [String]
e
    go (Failed [String] -> [String]
e) = ([String] -> [String]) -> Automaton p i o b
forall p i o a. ([String] -> [String]) -> Automaton p i o a
Failed [String] -> [String]
e
    go (Automaton p i o a
a :+++ Automaton p i o a
b) = Automaton p i o a -> Automaton p i o b
go Automaton p i o a
a Automaton p i o b -> Automaton p i o b -> Automaton p i o b
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton p i o a -> Automaton p i o b
go Automaton p i o a
b
    go (Yield o
o Automaton p i o a
r) = o -> Automaton p i o b -> Automaton p i o b
forall p i o a. o -> Automaton p i o a -> Automaton p i o a
Yield o
o (Automaton p i o a -> Automaton p i o b
go Automaton p i o a
r)
    go (Count p
p Automaton p i o a
r) = p -> Automaton p i o b -> Automaton p i o b
forall p i o a. p -> Automaton p i o a -> Automaton p i o a
Count p
p (Automaton p i o a -> Automaton p i o b
go Automaton p i o a
r)
    go (GetCount p -> Automaton p i o a
n) = (p -> Automaton p i o b) -> Automaton p i o b
forall p i o a. (p -> Automaton p i o a) -> Automaton p i o a
GetCount ((Automaton p i o a -> Automaton p i o b)
-> (p -> Automaton p i o a) -> p -> Automaton p i o b
forall a b. (a -> b) -> (p -> a) -> p -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Automaton p i o a -> Automaton p i o b
go p -> Automaton p i o a
n)

instance PhaserType Phase where
  toAutomaton :: forall p i o a. Monoid p => Phase p i o a -> Automaton p i o a
toAutomaton = Phase p i o a -> Automaton p i o a
forall p i o a. Monoid p => Phase p i o a -> Automaton p i o a
p2a
  fromAutomaton :: forall p i o a. Monoid p => Automaton p i o a -> Phase p i o a
fromAutomaton = Automaton p i o a -> Phase p i o a
forall p i o a. Monoid p => Automaton p i o a -> Phase p i o a
a2p
  toPhase :: forall p i o a. Monoid p => Phase p i o a -> Phase p i o a
toPhase = Phase p i o a -> Phase p i o a
forall a. a -> a
id
  fromPhase :: forall p i o a. Monoid p => Phase p i o a -> Phase p i o a
fromPhase = Phase p i o a -> Phase p i o a
forall a. a -> a
id
  $#$ :: forall p b c x t.
Monoid p =>
Phase p b c x -> (c -> t) -> Phase p b t x
($#$) = Phase p b c x -> (c -> t) -> Phase p b t x
forall {p} {s :: * -> * -> * -> * -> *}
       {s :: * -> * -> * -> * -> *} {i} {c} {a} {o}.
(Monoid p, PhaserType s, PhaserType s) =>
s p i c a -> (c -> o) -> s p i o a
source_p

{-# INLINE [1] p2a #-}
p2a :: Monoid p => Phase p i o a -> Automaton p i o a
p2a :: forall p i o a. Monoid p => Phase p i o a -> Automaton p i o a
p2a (Phase ([String] -> [String])
-> forall b. (a -> Automaton p i o b) -> Automaton p i o b
c) = ([String] -> [String])
-> forall b. (a -> Automaton p i o b) -> Automaton p i o b
c [String] -> [String]
forall a. a -> a
id a -> Automaton p i o a
forall p i o a. a -> Automaton p i o a
Result

{-# INLINABLE [1] a2p #-}
a2p :: Monoid p => Automaton p i o a -> Phase p i o a
a2p :: forall p i o a. Monoid p => Automaton p i o a -> Phase p i o a
a2p Automaton p i o a
a = (([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
forall p i o a.
(([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
Phase (\[String] -> [String]
e' a -> Automaton p i o b
c -> let
  continue :: Automaton p i o a -> Automaton p i o b
continue (Result a
r) = a -> Automaton p i o b
c a
r
  continue (Ready i -> Automaton p i o a
n [String] -> [String]
e) = (i -> Automaton p i o b)
-> ([String] -> [String]) -> Automaton p i o b
forall p i o a.
(i -> Automaton p i o a)
-> ([String] -> [String]) -> Automaton p i o a
Ready ((Automaton p i o a -> Automaton p i o b)
-> (i -> Automaton p i o a) -> i -> Automaton p i o b
forall a b. (a -> b) -> (i -> a) -> i -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Automaton p i o a -> Automaton p i o b
continue i -> Automaton p i o a
n) ([String] -> [String]
e' ([String] -> [String])
-> ([String] -> [String]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
e)
  continue (Failed [String] -> [String]
e) = ([String] -> [String]) -> Automaton p i o b
forall p i o a. ([String] -> [String]) -> Automaton p i o a
Failed ([String] -> [String]
e' ([String] -> [String])
-> ([String] -> [String]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
e)
  continue (Automaton p i o a
l :+++ Automaton p i o a
r) = Automaton p i o b -> Automaton p i o b
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (Automaton p i o a -> Automaton p i o b
continue Automaton p i o a
l Automaton p i o b -> Automaton p i o b -> Automaton p i o b
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton p i o a -> Automaton p i o b
continue Automaton p i o a
r)
  continue (Count p
p Automaton p i o a
r) = Automaton p i o b -> Automaton p i o b
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (p -> Automaton p i o b -> Automaton p i o b
forall p i o a. p -> Automaton p i o a -> Automaton p i o a
Count p
p (Automaton p i o a -> Automaton p i o b
continue Automaton p i o a
r))
  continue (Yield o
o Automaton p i o a
r) = Automaton p i o b -> Automaton p i o b
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (o -> Automaton p i o b -> Automaton p i o b
forall p i o a. o -> Automaton p i o a -> Automaton p i o a
Yield o
o (Automaton p i o a -> Automaton p i o b
continue Automaton p i o a
r))
  continue (GetCount p -> Automaton p i o a
n) = (p -> Automaton p i o b) -> Automaton p i o b
forall p i o a. (p -> Automaton p i o a) -> Automaton p i o a
GetCount ((Automaton p i o a -> Automaton p i o b)
-> (p -> Automaton p i o a) -> p -> Automaton p i o b
forall a b. (a -> b) -> (p -> a) -> p -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Automaton p i o a -> Automaton p i o b
continue p -> Automaton p i o a
n)
  in Automaton p i o a -> Automaton p i o b
continue Automaton p i o a
a
 )

{-# RULES
"p2a/a2p" forall a . p2a (a2p a) = a
"a2p/p2a" forall a . a2p (p2a a) = a
 #-}

instance PhaserType Automaton where
  toAutomaton :: forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
toAutomaton = Automaton p i o a -> Automaton p i o a
forall a. a -> a
id
  fromAutomaton :: forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
fromAutomaton = Automaton p i o a -> Automaton p i o a
forall a. a -> a
id
  toPhase :: forall p i o a. Monoid p => Automaton p i o a -> Phase p i o a
toPhase = Automaton p i o a -> Phase p i o a
forall p i o a. Monoid p => Automaton p i o a -> Phase p i o a
a2p
  fromPhase :: forall p i o a. Monoid p => Phase p i o a -> Automaton p i o a
fromPhase = Phase p i o a -> Automaton p i o a
forall p i o a. Monoid p => Phase p i o a -> Automaton p i o a
p2a
  $#$ :: forall p b c x t.
Monoid p =>
Automaton p b c x -> (c -> t) -> Automaton p b t x
($#$) = Automaton p b c x -> (c -> t) -> Automaton p b t x
forall p i c a t.
Automaton p i c a -> (c -> t) -> Automaton p i t a
source_a

chainWith :: forall p s d x a z b t c . (Monoid p, PhaserType s, PhaserType d) => (x -> a -> z) ->
  s p b c x -> d p c t a -> Automaton p b t z
chainWith :: forall p (s :: * -> * -> * -> * -> *) (d :: * -> * -> * -> * -> *)
       x a z b t c.
(Monoid p, PhaserType s, PhaserType d) =>
(x -> a -> z) -> s p b c x -> d p c t a -> Automaton p b t z
chainWith x -> a -> z
f s p b c x
a d p c t a
b = s p b c x -> Automaton p b c x
forall p i o a. Monoid p => s p i o a -> Automaton p i o a
forall (s :: * -> * -> * -> * -> *) p i o a.
(PhaserType s, Monoid p) =>
s p i o a -> Automaton p i o a
toAutomaton s p b c x
a Automaton p b c x -> Automaton p c t a -> Automaton p b t z
!!! d p c t a -> Automaton p c t a
forall p i o a. Monoid p => d p i o a -> Automaton p i o a
forall (s :: * -> * -> * -> * -> *) p i o a.
(PhaserType s, Monoid p) =>
s p i o a -> Automaton p i o a
toAutomaton d p c t a
b where
    (!!!) :: Automaton p b c x -> Automaton p c t a -> Automaton p b t z
    s :: Automaton p b c x
s@(Yield c
_ Automaton p b c x
_) !!! :: Automaton p b c x -> Automaton p c t a -> Automaton p b t z
!!! GetCount p -> Automaton p c t a
n = (p -> Automaton p b t z) -> Automaton p b t z
forall p i o a. (p -> Automaton p i o a) -> Automaton p i o a
GetCount (\p
p -> Automaton p b c x
s Automaton p b c x -> Automaton p c t a -> Automaton p b t z
!!! p -> Automaton p c t a
n p
p)
    s :: Automaton p b c x
s@(Yield c
_ Automaton p b c x
_) !!! (Automaton p c t a
a :+++ Automaton p c t a
b) = Automaton p b t z -> Automaton p b t z
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 ((Automaton p b c x
s Automaton p b c x -> Automaton p c t a -> Automaton p b t z
!!! Automaton p c t a
a) Automaton p b t z -> Automaton p b t z -> Automaton p b t z
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ (Automaton p b c x
s Automaton p b c x -> Automaton p c t a -> Automaton p b t z
!!! Automaton p c t a
b))
    s :: Automaton p b c x
s@(Yield c
_ Automaton p b c x
_) !!! Yield t
o Automaton p c t a
r = Automaton p b t z -> Automaton p b t z
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (t -> Automaton p b t z -> Automaton p b t z
forall p i o a. o -> Automaton p i o a -> Automaton p i o a
Yield t
o (Automaton p b c x
s Automaton p b c x -> Automaton p c t a -> Automaton p b t z
!!! Automaton p c t a
r))
    Yield c
o Automaton p b c x
r !!! Automaton p c t a
d = case Automaton p c t a -> Either (Automaton p b t a) (Automaton p c t a)
forall p i o a v.
Monoid p =>
Automaton p i o a -> Either (Automaton p v o a) (Automaton p i o a)
beforeStep' Automaton p c t a
d of
      Left Automaton p b t a
e ->  (a -> z) -> Automaton p b t a -> Automaton p b t z
forall a b. (a -> b) -> Automaton p b t a -> Automaton p b t b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> z
forall a. HasCallStack => a
undefined Automaton p b t a
e
      Right Automaton p c t a
d' -> let s :: Automaton p c t a
s = Automaton p c t a -> c -> Automaton p c t a
forall p i o a.
Monoid p =>
Automaton p i o a -> i -> Automaton p i o a
step' Automaton p c t a
d' c
o in Automaton p c t a
s Automaton p c t a -> Automaton p b t z -> Automaton p b t z
forall a b. a -> b -> b
`seq` (Automaton p b c x
r Automaton p b c x -> Automaton p c t a -> Automaton p b t z
!!! Automaton p c t a
s)
    Failed [String] -> [String]
e !!! Automaton p c t a
_ = ([String] -> [String]) -> Automaton p b t z
forall p i o a. ([String] -> [String]) -> Automaton p i o a
Failed [String] -> [String]
e
    Automaton p b c x
_ !!! Failed [String] -> [String]
e = ([String] -> [String]) -> Automaton p b t z
forall p i o a. ([String] -> [String]) -> Automaton p i o a
Failed [String] -> [String]
e
    Result x
a !!! Automaton p c t a
d = x -> a -> z
f x
a (a -> z) -> Automaton p b t a -> Automaton p b t z
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Automaton p c t a -> Automaton p b t a
forall p i o a z.
Monoid p =>
Automaton p i o a -> Automaton p z o a
starve Automaton p c t a
d
    Count p
p Automaton p b c x
r !!! Automaton p c t a
d = Automaton p b t z -> Automaton p b t z
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (p -> Automaton p b t z -> Automaton p b t z
forall p i o a. p -> Automaton p i o a -> Automaton p i o a
Count p
p (Automaton p b c x
r Automaton p b c x -> Automaton p c t a -> Automaton p b t z
!!! Automaton p c t a
d))
    Automaton p b c x
s !!! Yield t
o Automaton p c t a
r = Automaton p b t z -> Automaton p b t z
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (t -> Automaton p b t z -> Automaton p b t z
forall p i o a. o -> Automaton p i o a -> Automaton p i o a
Yield t
o (Automaton p b c x
s Automaton p b c x -> Automaton p c t a -> Automaton p b t z
!!! Automaton p c t a
r))
    Automaton p b c x
s !!! Count p
p Automaton p c t a
r = Automaton p b t z -> Automaton p b t z
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (p -> Automaton p b t z -> Automaton p b t z
forall p i o a. p -> Automaton p i o a -> Automaton p i o a
Count p
p (Automaton p b c x
s Automaton p b c x -> Automaton p c t a -> Automaton p b t z
!!! Automaton p c t a
r))
    Automaton p b c x
s !!! GetCount p -> Automaton p c t a
n = (p -> Automaton p b t z) -> Automaton p b t z
forall p i o a. (p -> Automaton p i o a) -> Automaton p i o a
GetCount (\p
p -> Automaton p b c x
s Automaton p b c x -> Automaton p c t a -> Automaton p b t z
!!! p -> Automaton p c t a
n p
p)
    (Automaton p b c x
a :+++ Automaton p b c x
b) !!! Automaton p c t a
d = Automaton p b t z -> Automaton p b t z
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 ((Automaton p b c x
a Automaton p b c x -> Automaton p c t a -> Automaton p b t z
!!! Automaton p c t a
d) Automaton p b t z -> Automaton p b t z -> Automaton p b t z
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ (Automaton p b c x
b Automaton p b c x -> Automaton p c t a -> Automaton p b t z
!!! Automaton p c t a
d))
    Ready b -> Automaton p b c x
n [String] -> [String]
e !!! Automaton p c t a
d = (b -> Automaton p b t z)
-> ([String] -> [String]) -> Automaton p b t z
forall p i o a.
(i -> Automaton p i o a)
-> ([String] -> [String]) -> Automaton p i o a
Ready (\b
t -> b -> Automaton p b c x
n b
t Automaton p b c x -> Automaton p c t a -> Automaton p b t z
!!! Automaton p c t a
d) [String] -> [String]
e
    GetCount p -> Automaton p b c x
n !!! Automaton p c t a
d = (p -> Automaton p b t z) -> Automaton p b t z
forall p i o a. (p -> Automaton p i o a) -> Automaton p i o a
GetCount (\p
p -> p -> Automaton p b c x
n p
p Automaton p b c x -> Automaton p c t a -> Automaton p b t z
!!! Automaton p c t a
d)

-- | Take the incremental output of the first argument and use it as input
-- for the second argument. Discard the final output of the first argument.
{-# INLINE[1] (>>#) #-}
(>>#) :: (Monoid p, PhaserType s, PhaserType d) => s p b c x -> d p c t a -> Automaton p b t a
>># :: forall p (s :: * -> * -> * -> * -> *) (d :: * -> * -> * -> * -> *)
       b c x t a.
(Monoid p, PhaserType s, PhaserType d) =>
s p b c x -> d p c t a -> Automaton p b t a
(>>#) = (x -> a -> a) -> s p b c x -> d p c t a -> Automaton p b t a
forall p (s :: * -> * -> * -> * -> *) (d :: * -> * -> * -> * -> *)
       x a z b t c.
(Monoid p, PhaserType s, PhaserType d) =>
(x -> a -> z) -> s p b c x -> d p c t a -> Automaton p b t z
chainWith ((a -> x -> a) -> x -> a -> a
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> x -> a
forall a b. a -> b -> a
const)

source_a :: Automaton p i c a -> (c -> t) -> Automaton p i t a
{-# INLINE[1] source_a #-}
source_a :: forall p i c a t.
Automaton p i c a -> (c -> t) -> Automaton p i t a
source_a Automaton p i c a
a c -> t
f = Automaton p i c a -> Automaton p i t a
forall {p} {i} {a}. Automaton p i c a -> Automaton p i t a
go Automaton p i c a
a where
  go :: Automaton p i c a -> Automaton p i t a
go (Result a
a) = a -> Automaton p i t a
forall p i o a. a -> Automaton p i o a
Result a
a
  go (Ready i -> Automaton p i c a
p [String] -> [String]
e) = (i -> Automaton p i t a)
-> ([String] -> [String]) -> Automaton p i t a
forall p i o a.
(i -> Automaton p i o a)
-> ([String] -> [String]) -> Automaton p i o a
Ready ((Automaton p i c a -> Automaton p i t a)
-> (i -> Automaton p i c a) -> i -> Automaton p i t a
forall a b. (a -> b) -> (i -> a) -> i -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Automaton p i c a -> Automaton p i t a
go i -> Automaton p i c a
p) [String] -> [String]
e
  go (Failed [String] -> [String]
e) = ([String] -> [String]) -> Automaton p i t a
forall p i o a. ([String] -> [String]) -> Automaton p i o a
Failed [String] -> [String]
e
  go (Automaton p i c a
a :+++ Automaton p i c a
b) = Automaton p i c a -> Automaton p i t a
go Automaton p i c a
a Automaton p i t a -> Automaton p i t a -> Automaton p i t a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton p i c a -> Automaton p i t a
go Automaton p i c a
b
  go (Yield c
o Automaton p i c a
r) = t -> Automaton p i t a -> Automaton p i t a
forall p i o a. o -> Automaton p i o a -> Automaton p i o a
Yield (c -> t
f c
o) (Automaton p i c a -> Automaton p i t a
go Automaton p i c a
r)
  go (Count p
p Automaton p i c a
r) = p -> Automaton p i t a -> Automaton p i t a
forall p i o a. p -> Automaton p i o a -> Automaton p i o a
Count p
p (Automaton p i c a -> Automaton p i t a
go Automaton p i c a
r)
  go (GetCount p -> Automaton p i c a
n) = (p -> Automaton p i t a) -> Automaton p i t a
forall p i o a. (p -> Automaton p i o a) -> Automaton p i o a
GetCount ((Automaton p i c a -> Automaton p i t a)
-> (p -> Automaton p i c a) -> p -> Automaton p i t a
forall a b. (a -> b) -> (p -> a) -> p -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Automaton p i c a -> Automaton p i t a
go p -> Automaton p i c a
n)

{-# INLINE[1] source_p #-}
source_p :: s p i c a -> (c -> o) -> s p i o a
source_p s p i c a
p c -> o
f = Automaton p i o a -> s p i o a
forall p i o a. Monoid p => Automaton p i o a -> s p i o a
forall (s :: * -> * -> * -> * -> *) p i o a.
(PhaserType s, Monoid p) =>
Automaton p i o a -> s p i o a
fromAutomaton (Automaton p i o a -> s p i o a) -> Automaton p i o a -> s p i o a
forall a b. (a -> b) -> a -> b
$ Automaton p i c a -> (c -> o) -> Automaton p i o a
forall p i c a t.
Automaton p i c a -> (c -> t) -> Automaton p i t a
source_a (s p i c a -> Automaton p i c a
forall p i o a. Monoid p => s p i o a -> Automaton p i o a
forall (s :: * -> * -> * -> * -> *) p i o a.
(PhaserType s, Monoid p) =>
s p i o a -> Automaton p i o a
toAutomaton s p i c a
p) c -> o
f

{-# RULES
"$#$/$#$/1" forall a f1 f2 . source_a (source_a a f1) f2 = source_a a (f2 . f1)
"$#$/$#$/2" forall a f1 f2 . source_p (source_p a f1) f2 = source_p a (f2 . f1)
"toAutomaton/$#$" forall p f . toAutomaton (source_p p f) = source_a (toAutomaton p) f
 #-}

-- | If parsing fails in the right argument: prepend the left argument to the
-- errors
infixr 1 <?>
String
e <?> :: String -> Phase p i o a -> Phase p i o a
<?> Phase ([String] -> [String])
-> forall b. (a -> Automaton p i o b) -> Automaton p i o b
s = (([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
forall p i o a.
(([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
Phase (\[String] -> [String]
e1 -> ([String] -> [String])
-> forall b. (a -> Automaton p i o b) -> Automaton p i o b
s ((String
e String -> [String] -> [String]
forall a. a -> [a] -> [a]
:) ([String] -> [String])
-> ([String] -> [String]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
e1))

-- | Change the counter type of a Phaser object. May cause 'getCount' to
-- behave differently from expected: counter increments inside the right hand
-- argument are visible outside but not vice versa.
infixr 1 >#>
(>#>) :: forall s p0 p i o a . (PhaserType s, Monoid p0, Monoid p) =>
  (p0 -> p) -> s p0 i o a -> s p i o a
{-# INLINABLE [1] (>#>) #-}
p0 -> p
f >#> :: forall (s :: * -> * -> * -> * -> *) p0 p i o a.
(PhaserType s, Monoid p0, Monoid p) =>
(p0 -> p) -> s p0 i o a -> s p i o a
>#> s p0 i o a
p = Automaton p i o a -> s p i o a
forall p i o a. Monoid p => Automaton p i o a -> s p i o a
forall (s :: * -> * -> * -> * -> *) p i o a.
(PhaserType s, Monoid p) =>
Automaton p i o a -> s p i o a
fromAutomaton (Automaton p i o a -> s p i o a) -> Automaton p i o a -> s p i o a
forall a b. (a -> b) -> a -> b
$ p0 -> Automaton p0 i o a -> Automaton p i o a
(PhaserType s, Monoid p0, Monoid p) =>
p0 -> Automaton p0 i o a -> Automaton p i o a
go p0
forall a. Monoid a => a
mempty (Automaton p0 i o a -> Automaton p i o a)
-> Automaton p0 i o a -> Automaton p i o a
forall a b. (a -> b) -> a -> b
$ s p0 i o a -> Automaton p0 i o a
forall p i o a. Monoid p => s p i o a -> Automaton p i o a
forall (s :: * -> * -> * -> * -> *) p i o a.
(PhaserType s, Monoid p) =>
s p i o a -> Automaton p i o a
toAutomaton s p0 i o a
p where
  go :: (PhaserType s, Monoid p0, Monoid p) => p0 -> Automaton p0 i o a -> Automaton p i o a
  go :: (PhaserType s, Monoid p0, Monoid p) =>
p0 -> Automaton p0 i o a -> Automaton p i o a
go p0
_ (Result a
a) = a -> Automaton p i o a
forall p i o a. a -> Automaton p i o a
Result a
a
  go p0
p (Ready i -> Automaton p0 i o a
n [String] -> [String]
e) = (i -> Automaton p i o a)
-> ([String] -> [String]) -> Automaton p i o a
forall p i o a.
(i -> Automaton p i o a)
-> ([String] -> [String]) -> Automaton p i o a
Ready ((Automaton p0 i o a -> Automaton p i o a)
-> (i -> Automaton p0 i o a) -> i -> Automaton p i o a
forall a b. (a -> b) -> (i -> a) -> i -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (p0 -> Automaton p0 i o a -> Automaton p i o a
(PhaserType s, Monoid p0, Monoid p) =>
p0 -> Automaton p0 i o a -> Automaton p i o a
go p0
p) i -> Automaton p0 i o a
n) [String] -> [String]
e
  go p0
_ (Failed [String] -> [String]
e) = ([String] -> [String]) -> Automaton p i o a
forall p i o a. ([String] -> [String]) -> Automaton p i o a
Failed [String] -> [String]
e
  go p0
p (Automaton p0 i o a
a :+++ Automaton p0 i o a
b) = p0 -> Automaton p0 i o a -> Automaton p i o a
(PhaserType s, Monoid p0, Monoid p) =>
p0 -> Automaton p0 i o a -> Automaton p i o a
go p0
p Automaton p0 i o a
a Automaton p i o a -> Automaton p i o a -> Automaton p i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ p0 -> Automaton p0 i o a -> Automaton p i o a
(PhaserType s, Monoid p0, Monoid p) =>
p0 -> Automaton p0 i o a -> Automaton p i o a
go p0
p Automaton p0 i o a
b
  go p0
p (Yield o
t Automaton p0 i o a
r) = o -> Automaton p i o a -> Automaton p i o a
forall p i o a. o -> Automaton p i o a -> Automaton p i o a
Yield o
t (p0 -> Automaton p0 i o a -> Automaton p i o a
(PhaserType s, Monoid p0, Monoid p) =>
p0 -> Automaton p0 i o a -> Automaton p i o a
go p0
p Automaton p0 i o a
r)
  go p0
p0 (Count p0
p Automaton p0 i o a
r) = let
    p' :: p0
p' = p0 -> p0 -> p0
forall a. Monoid a => a -> a -> a
mappend p0
p0 p0
p
    in p0
p' p0 -> Automaton p i o a -> Automaton p i o a
forall a b. a -> b -> b
`seq` p -> Automaton p i o a -> Automaton p i o a
forall p i o a. p -> Automaton p i o a -> Automaton p i o a
Count (p0 -> p
f p0
p) (p0 -> Automaton p0 i o a -> Automaton p i o a
(PhaserType s, Monoid p0, Monoid p) =>
p0 -> Automaton p0 i o a -> Automaton p i o a
go p0
p' Automaton p0 i o a
r)
  go p0
p (GetCount p0 -> Automaton p0 i o a
n) = p0 -> Automaton p0 i o a -> Automaton p i o a
(PhaserType s, Monoid p0, Monoid p) =>
p0 -> Automaton p0 i o a -> Automaton p i o a
go p0
p (p0 -> Automaton p0 i o a
n p0
p)

-- | Return one item of the input.
get :: Phase p i o i
get :: forall p i o. Phase p i o i
get = (([String] -> [String])
 -> forall b. (i -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o i
forall p i o a.
(([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
Phase (\[String] -> [String]
x i -> Automaton p i o b
y -> (i -> Automaton p i o b)
-> ([String] -> [String]) -> Automaton p i o b
forall p i o a.
(i -> Automaton p i o a)
-> ([String] -> [String]) -> Automaton p i o a
Ready i -> Automaton p i o b
y [String] -> [String]
x)

-- | Increment the counter
count :: p -> Phase p i o ()
{-# INLINE [1] count #-}
count :: forall p i o. p -> Phase p i o ()
count p
f = (([String] -> [String])
 -> forall b. (() -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o ()
forall p i o a.
(([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
Phase (\[String] -> [String]
_ () -> Automaton p i o b
c -> p -> Automaton p i o b -> Automaton p i o b
forall p i o a. p -> Automaton p i o a -> Automaton p i o a
Count p
f (() -> Automaton p i o b
c ()))

-- | Retrieve the current counter. Counter values are shared between arguments
-- to '>>#' except when at least one argument is produced by an incompatible function.
-- All functions in this module are compatible unless noted in the corresponding
-- documentation.
getCount :: Phase p i o p
getCount :: forall p i o. Phase p i o p
getCount = (([String] -> [String])
 -> forall b. (p -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o p
forall p i o a.
(([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
Phase (\[String] -> [String]
_ -> (p -> Automaton p i o b) -> Automaton p i o b
forall p i o a. (p -> Automaton p i o a) -> Automaton p i o a
GetCount)

-- | Yield one item for the incremental output
yield :: o -> Phase p i o ()
{-# INLINE [1] yield #-}
yield :: forall o p i. o -> Phase p i o ()
yield o
o = (([String] -> [String])
 -> forall b. (() -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o ()
forall p i o a.
(([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
Phase (\[String] -> [String]
_ () -> Automaton p i o b
c -> o -> Automaton p i o b -> Automaton p i o b
forall p i o a. o -> Automaton p i o a -> Automaton p i o a
Yield o
o (() -> Automaton p i o b
c ()))

-- | Fail if any more input is provided.
eof :: (Monoid p) => Phase p i o ()
eof :: forall p i o. Monoid p => Phase p i o ()
eof = (([String] -> [String])
 -> forall b. (() -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o ()
forall p i o a.
(([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
Phase (\[String] -> [String]
e () -> Automaton p i o b
c -> Automaton p i o b -> Automaton p i o b
forall p i o a z.
Monoid p =>
Automaton p i o a -> Automaton p z o a
starve (() -> Automaton p i o b
c ()))

-- | Fail unless more input is provided.
neof :: (Monoid p) => Phase p i o ()
neof :: forall p i o. Monoid p => Phase p i o ()
neof = (([String] -> [String])
 -> forall b. (() -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o ()
forall p i o a.
(([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
Phase (\[String] -> [String]
e () -> Automaton p i o b
c -> case Automaton p i o b -> Either (Automaton p i o b) (Automaton p i o b)
forall p i o a v.
Monoid p =>
Automaton p i o a -> Either (Automaton p v o a) (Automaton p i o a)
beforeStep' (() -> Automaton p i o b
c ()) of
  Right Automaton p i o b
r -> Automaton p i o b
r
  Left Automaton p i o b
r -> Automaton p i o b
r
 )

-- | Insert one value back into the input. May be used for implementing
-- lookahead. Can have counter-intuitive interactions with 'getCount'.
put1 :: (Monoid p) => i -> Phase p i o ()
{-# INLINE [1] put1 #-}
put1 :: forall p i o. Monoid p => i -> Phase p i o ()
put1 i
i = (([String] -> [String])
 -> forall b. (() -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o ()
forall p i o a.
(([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
Phase (\[String] -> [String]
_ () -> Automaton p i o b
c -> case Automaton p i o b -> Either (Automaton p i o b) (Automaton p i o b)
forall p i o a v.
Monoid p =>
Automaton p i o a -> Either (Automaton p v o a) (Automaton p i o a)
beforeStep' (() -> Automaton p i o b
c ()) of
  Right Automaton p i o b
n -> Automaton p i o b -> i -> Automaton p i o b
forall p i o a.
Monoid p =>
Automaton p i o a -> i -> Automaton p i o a
step' Automaton p i o b
n i
i
  Left Automaton p i o b
e -> Automaton p i o b
e
 )

-- | Put a list of values back into the input. Can have counter-intuitive
-- interactions with 'getCount'
put :: (Monoid p) => [i] -> Phase p i o ()
{-# INLINE [1] put #-}
put :: forall p i o. Monoid p => [i] -> Phase p i o ()
put [i]
i = (([String] -> [String])
 -> forall b. (() -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o ()
forall p i o a.
(([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
Phase (\[String] -> [String]
_ () -> Automaton p i o b
c -> Automaton p i o b -> [i] -> Automaton p i o b
forall p i o a.
Monoid p =>
Automaton p i o a -> [i] -> Automaton p i o a
run' (() -> Automaton p i o b
c ()) [i]
i)

-- | Use the argument to control the input passed to the following 'Phase'
-- actions.
-- @
--   buffer (return True)
-- @
-- is equivalent to
-- @
--   return ()
-- @
-- @
--   buffer (return False)
-- @
-- is equivalent to
-- @
--   eof
-- @
-- @
--   buffer (True <$ yield 'a')
-- @
-- is equivalent to
-- @
--   put1 'a'
-- *
-- etc.
buffer :: (Monoid p, PhaserType s) => s () i i Bool -> Phase p i o ()
buffer :: forall p (s :: * -> * -> * -> * -> *) i o.
(Monoid p, PhaserType s) =>
s () i i Bool -> Phase p i o ()
buffer s () i i Bool
p' = let
  p :: Automaton () i i Bool
p = s () i i Bool -> Automaton () i i Bool
forall p i o a. Monoid p => s p i o a -> Automaton p i o a
forall (s :: * -> * -> * -> * -> *) p i o a.
(PhaserType s, Monoid p) =>
s p i o a -> Automaton p i o a
toAutomaton s () i i Bool
p'
  in (([String] -> [String])
 -> forall b. (() -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o ()
forall p i o a.
(([String] -> [String])
 -> forall b. (a -> Automaton p i o b) -> Automaton p i o b)
-> Phase p i o a
Phase (\[String] -> [String]
e () -> Automaton p i o b
c -> let
    go :: Automaton () i i Bool -> Automaton p i o a -> Automaton p i o a
go (Result Bool
True) Automaton p i o a
t = Automaton p i o a
t
    go (Result Bool
False) Automaton p i o a
t = Automaton p i o a -> Automaton p i o a
forall p i o a z.
Monoid p =>
Automaton p i o a -> Automaton p z o a
starve Automaton p i o a
t
    go (Ready i -> Automaton () i i Bool
p [String] -> [String]
e') Automaton p i o a
t = (i -> Automaton p i o a)
-> ([String] -> [String]) -> Automaton p i o a
forall p i o a.
(i -> Automaton p i o a)
-> ([String] -> [String]) -> Automaton p i o a
Ready (\i
i -> Automaton () i i Bool -> Automaton p i o a -> Automaton p i o a
go (i -> Automaton () i i Bool
p i
i) Automaton p i o a
t) ([String] -> [String]
e ([String] -> [String])
-> ([String] -> [String]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
e')
    go (Failed [String] -> [String]
e') Automaton p i o a
t = ([String] -> [String]) -> Automaton p i o a
forall p i o a. ([String] -> [String]) -> Automaton p i o a
Failed ([String] -> [String]
e ([String] -> [String])
-> ([String] -> [String]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
e')
    go (Automaton () i i Bool
a :+++ Automaton () i i Bool
b) Automaton p i o a
t = Automaton p i o a -> Automaton p i o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (Automaton () i i Bool -> Automaton p i o a -> Automaton p i o a
go Automaton () i i Bool
a Automaton p i o a
t Automaton p i o a -> Automaton p i o a -> Automaton p i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton () i i Bool -> Automaton p i o a -> Automaton p i o a
go Automaton () i i Bool
b Automaton p i o a
t)
    go (Yield i
i Automaton () i i Bool
r) Automaton p i o a
t = case Automaton p i o a -> Either (Automaton p i o a) (Automaton p i o a)
forall p i o a v.
Monoid p =>
Automaton p i o a -> Either (Automaton p v o a) (Automaton p i o a)
beforeStep' Automaton p i o a
t of
      Right Automaton p i o a
n -> Automaton () i i Bool -> Automaton p i o a -> Automaton p i o a
go Automaton () i i Bool
r (Automaton p i o a -> Automaton p i o a)
-> Automaton p i o a -> Automaton p i o a
forall a b. (a -> b) -> a -> b
$ Automaton p i o a -> i -> Automaton p i o a
forall p i o a.
Monoid p =>
Automaton p i o a -> i -> Automaton p i o a
step' Automaton p i o a
n i
i
      Left Automaton p i o a
e -> Automaton p i o a
e
    go (Count () Automaton () i i Bool
r) Automaton p i o a
t = Automaton () i i Bool -> Automaton p i o a -> Automaton p i o a
go Automaton () i i Bool
r Automaton p i o a
t
    go (GetCount () -> Automaton () i i Bool
n) Automaton p i o a
t = Automaton () i i Bool -> Automaton p i o a -> Automaton p i o a
go (() -> Automaton () i i Bool
n ()) Automaton p i o a
t
    in Automaton () i i Bool -> Automaton p i o b -> Automaton p i o b
forall {p} {i} {o} {a}.
Monoid p =>
Automaton () i i Bool -> Automaton p i o a -> Automaton p i o a
go Automaton () i i Bool
p (() -> Automaton p i o b
c ())
   )

{-# INLINABLE [1] prune1 #-}
prune1 :: Automaton a i o a -> Automaton a i o a
prune1 (Failed [String] -> [String]
e1 :+++ Failed [String] -> [String]
e2) = ([String] -> [String]) -> Automaton a i o a
forall p i o a. ([String] -> [String]) -> Automaton p i o a
Failed ([String] -> [String]
e1 ([String] -> [String])
-> ([String] -> [String]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
e2)
prune1 (Failed [String] -> [String]
e1 :+++ Ready i -> Automaton a i o a
n [String] -> [String]
e2) = (i -> Automaton a i o a)
-> ([String] -> [String]) -> Automaton a i o a
forall p i o a.
(i -> Automaton p i o a)
-> ([String] -> [String]) -> Automaton p i o a
Ready i -> Automaton a i o a
n ([String] -> [String]
e1 ([String] -> [String])
-> ([String] -> [String]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
e2)
prune1 (Ready i -> Automaton a i o a
n [String] -> [String]
e1 :+++ Failed [String] -> [String]
e2) = (i -> Automaton a i o a)
-> ([String] -> [String]) -> Automaton a i o a
forall p i o a.
(i -> Automaton p i o a)
-> ([String] -> [String]) -> Automaton p i o a
Ready i -> Automaton a i o a
n ([String] -> [String]
e1 ([String] -> [String])
-> ([String] -> [String]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
e2)
prune1 (Ready i -> Automaton a i o a
n1 [String] -> [String]
e1 :+++ Ready i -> Automaton a i o a
n2 [String] -> [String]
e2) =
  (i -> Automaton a i o a)
-> ([String] -> [String]) -> Automaton a i o a
forall p i o a.
(i -> Automaton p i o a)
-> ([String] -> [String]) -> Automaton p i o a
Ready (\i
i -> Automaton a i o a -> Automaton a i o a
prune1 (Automaton a i o a -> Automaton a i o a)
-> Automaton a i o a -> Automaton a i o a
forall a b. (a -> b) -> a -> b
$ i -> Automaton a i o a
n1 i
i Automaton a i o a -> Automaton a i o a -> Automaton a i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ i -> Automaton a i o a
n2 i
i) ([String] -> [String]
e1 ([String] -> [String])
-> ([String] -> [String]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
e2)
prune1 (r :: Automaton a i o a
r@(Result a
_) :+++ Failed [String] -> [String]
_) = Automaton a i o a
r
prune1 (Failed [String] -> [String]
_ :+++ r :: Automaton a i o a
r@(Result a
_)) = Automaton a i o a
r
prune1 r :: Automaton a i o a
r@(Failed [String] -> [String]
_ :+++ (Automaton a i o a
_ :+++ Failed [String] -> [String]
_)) = Automaton a i o a
r
prune1 (f :: Automaton a i o a
f@(Failed [String] -> [String]
_) :+++ (Automaton a i o a
a :+++ Automaton a i o a
b)) = Automaton a i o a -> Automaton a i o a
prune1 (Automaton a i o a -> Automaton a i o a
prune1 (Automaton a i o a
f Automaton a i o a -> Automaton a i o a -> Automaton a i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton a i o a
a) Automaton a i o a -> Automaton a i o a -> Automaton a i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton a i o a
b)
prune1 ((Automaton a i o a
a :+++ Automaton a i o a
b) :+++ f :: Automaton a i o a
f@(Failed [String] -> [String]
_)) = Automaton a i o a -> Automaton a i o a
prune1 (Automaton a i o a
a Automaton a i o a -> Automaton a i o a -> Automaton a i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton a i o a -> Automaton a i o a
prune1 (Automaton a i o a
b Automaton a i o a -> Automaton a i o a -> Automaton a i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton a i o a
f))
prune1 (f :: Automaton a i o a
f@(Failed [String] -> [String]
_) :+++ Yield o
o Automaton a i o a
r) = Automaton a i o a -> Automaton a i o a
prune1 (o -> Automaton a i o a -> Automaton a i o a
forall p i o a. o -> Automaton p i o a -> Automaton p i o a
Yield o
o (Automaton a i o a -> Automaton a i o a
prune1 (Automaton a i o a
f Automaton a i o a -> Automaton a i o a -> Automaton a i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton a i o a
r)))
prune1 (Yield o
o Automaton a i o a
r :+++ f :: Automaton a i o a
f@(Failed [String] -> [String]
_)) = Automaton a i o a -> Automaton a i o a
prune1 (o -> Automaton a i o a -> Automaton a i o a
forall p i o a. o -> Automaton p i o a -> Automaton p i o a
Yield o
o (Automaton a i o a -> Automaton a i o a
prune1 (Automaton a i o a
r Automaton a i o a -> Automaton a i o a -> Automaton a i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton a i o a
f)))
prune1 (a :: Automaton a i o a
a@(Ready i -> Automaton a i o a
_ [String] -> [String]
_) :+++ (b :: Automaton a i o a
b@(Ready i -> Automaton a i o a
_ [String] -> [String]
_) :+++ Automaton a i o a
c)) = Automaton a i o a -> Automaton a i o a
prune1 (Automaton a i o a -> Automaton a i o a
prune1 (Automaton a i o a
a Automaton a i o a -> Automaton a i o a -> Automaton a i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton a i o a
b) Automaton a i o a -> Automaton a i o a -> Automaton a i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton a i o a
c)
prune1 ((Automaton a i o a
a :+++ b :: Automaton a i o a
b@(Ready i -> Automaton a i o a
_ [String] -> [String]
_)) :+++ c :: Automaton a i o a
c@(Ready i -> Automaton a i o a
_ [String] -> [String]
_)) = Automaton a i o a -> Automaton a i o a
prune1 (Automaton a i o a
a Automaton a i o a -> Automaton a i o a -> Automaton a i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton a i o a -> Automaton a i o a
prune1 (Automaton a i o a
b Automaton a i o a -> Automaton a i o a -> Automaton a i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton a i o a
c))
prune1 (GetCount a -> Automaton a i o a
a :+++ GetCount a -> Automaton a i o a
b) = (a -> Automaton a i o a) -> Automaton a i o a
forall p i o a. (p -> Automaton p i o a) -> Automaton p i o a
GetCount (\a
p -> Automaton a i o a -> Automaton a i o a
prune1 (a -> Automaton a i o a
a a
p Automaton a i o a -> Automaton a i o a -> Automaton a i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ a -> Automaton a i o a
b a
p))
prune1 ((Automaton a i o a
a :+++ b :: Automaton a i o a
b@(GetCount a -> Automaton a i o a
_)) :+++ c :: Automaton a i o a
c@(GetCount a -> Automaton a i o a
_)) =
  Automaton a i o a -> Automaton a i o a
prune1 (Automaton a i o a
a Automaton a i o a -> Automaton a i o a -> Automaton a i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton a i o a -> Automaton a i o a
prune1 (Automaton a i o a
b Automaton a i o a -> Automaton a i o a -> Automaton a i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton a i o a
c))
prune1 (a :: Automaton a i o a
a@(GetCount a -> Automaton a i o a
_) :+++ (b :: Automaton a i o a
b@(GetCount a -> Automaton a i o a
_) :+++ Automaton a i o a
c)) =
  Automaton a i o a -> Automaton a i o a
prune1 (Automaton a i o a -> Automaton a i o a
prune1 (Automaton a i o a
a Automaton a i o a -> Automaton a i o a -> Automaton a i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton a i o a
b) Automaton a i o a -> Automaton a i o a -> Automaton a i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton a i o a
c)
prune1 (Count a
p (Count a
q Automaton a i o a
r)) = Automaton a i o a -> Automaton a i o a
prune1 (Automaton a i o a -> Automaton a i o a)
-> Automaton a i o a -> Automaton a i o a
forall a b. (a -> b) -> a -> b
$ let t :: a
t = a -> a -> a
forall a. Monoid a => a -> a -> a
mappend a
p a
q in a
t a -> Automaton a i o a -> Automaton a i o a
forall a b. a -> b -> b
`seq` a -> Automaton a i o a -> Automaton a i o a
forall p i o a. p -> Automaton p i o a -> Automaton p i o a
Count a
t Automaton a i o a
r
prune1 (Count a
p (Yield o
o Automaton a i o a
r)) =
  Automaton a i o a -> Automaton a i o a
prune1 (o -> Automaton a i o a -> Automaton a i o a
forall p i o a. o -> Automaton p i o a -> Automaton p i o a
Yield o
o (Automaton a i o a -> Automaton a i o a
prune1 (a -> Automaton a i o a -> Automaton a i o a
forall p i o a. p -> Automaton p i o a -> Automaton p i o a
Count a
p Automaton a i o a
r)))
prune1 (Yield o
_ f :: Automaton a i o a
f@(Failed [String] -> [String]
_)) = Automaton a i o a
f
prune1 (Yield o
_ f :: Automaton a i o a
f@(Count a
_ (Failed [String] -> [String]
_))) = Automaton a i o a
f
prune1 Automaton a i o a
a = Automaton a i o a
a

{-# RULES
"prune1/prune1" forall a . prune1 (prune1 a) = prune1 a
  #-}

-- | Remove an 'Automaton''s ability to consume further input
starve :: (Monoid p) => Automaton p i o a -> Automaton p z o a
{-# INLINABLE [1] starve #-}
starve :: forall p i o a z.
Monoid p =>
Automaton p i o a -> Automaton p z o a
starve (Result a
a) = a -> Automaton p z o a
forall p i o a. a -> Automaton p i o a
Result a
a
starve (Ready i -> Automaton p i o a
_ [String] -> [String]
e) = ([String] -> [String]) -> Automaton p z o a
forall p i o a. ([String] -> [String]) -> Automaton p i o a
Failed [String] -> [String]
e
starve (Failed [String] -> [String]
e) = ([String] -> [String]) -> Automaton p z o a
forall p i o a. ([String] -> [String]) -> Automaton p i o a
Failed [String] -> [String]
e
starve (Automaton p i o a
a :+++ Automaton p i o a
b) = Automaton p z o a -> Automaton p z o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (Automaton p i o a -> Automaton p z o a
forall p i o a z.
Monoid p =>
Automaton p i o a -> Automaton p z o a
starve Automaton p i o a
a Automaton p z o a -> Automaton p z o a -> Automaton p z o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton p i o a -> Automaton p z o a
forall p i o a z.
Monoid p =>
Automaton p i o a -> Automaton p z o a
starve Automaton p i o a
b)
starve (Yield o
o Automaton p i o a
r) = Automaton p z o a -> Automaton p z o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (o -> Automaton p z o a -> Automaton p z o a
forall p i o a. o -> Automaton p i o a -> Automaton p i o a
Yield o
o (Automaton p i o a -> Automaton p z o a
forall p i o a z.
Monoid p =>
Automaton p i o a -> Automaton p z o a
starve Automaton p i o a
r))
starve (Count p
p Automaton p i o a
r) = Automaton p z o a -> Automaton p z o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (p -> Automaton p z o a -> Automaton p z o a
forall p i o a. p -> Automaton p i o a -> Automaton p i o a
Count p
p (Automaton p i o a -> Automaton p z o a
forall p i o a z.
Monoid p =>
Automaton p i o a -> Automaton p z o a
starve Automaton p i o a
r))
starve (GetCount p -> Automaton p i o a
n) = (p -> Automaton p z o a) -> Automaton p z o a
forall p i o a. (p -> Automaton p i o a) -> Automaton p i o a
GetCount ((Automaton p i o a -> Automaton p z o a)
-> (p -> Automaton p i o a) -> p -> Automaton p z o a
forall a b. (a -> b) -> (p -> a) -> p -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Automaton p i o a -> Automaton p z o a
forall p i o a z.
Monoid p =>
Automaton p i o a -> Automaton p z o a
starve p -> Automaton p i o a
n)

{-# RULES
"starve/starve" forall a . starve (starve a) = starve a
  #-}

-- | Take a 'Phase' or 'Automaton' which doesn't 'yield' anything and allow
-- it to be used in a chain containing yield statements
fitYield :: PhaserType s => s p i Void a -> s p i o a
fitYield :: forall (s :: * -> * -> * -> * -> *) p i a o.
PhaserType s =>
s p i Void a -> s p i o a
fitYield = s p i Void a -> s p i o a
forall a b. a -> b
unsafeCoerce

-- | Take a 'Phase' or 'Automaton' which doesn't consume any input and allow
-- it to be composed with input consuming objects
fitGet :: PhaserType s => s p Void o a -> s p i o a
fitGet :: forall (s :: * -> * -> * -> * -> *) p o a i.
PhaserType s =>
s p Void o a -> s p i o a
fitGet = s p Void o a -> s p i o a
forall a b. a -> b
unsafeCoerce

-- | Optional pre-processing of an automaton before passing it more input.
-- Produces 'Right' with all "final outputs" and errors stripped if the
-- automaton can accept more input, and 'Left' with everything except errors
-- stripped if it cannot accept more input.
beforeStep :: (Monoid p) => Automaton p i o a ->
  Either (Automaton p v o a) (Automaton p i o a)
beforeStep :: forall p i o a v.
Monoid p =>
Automaton p i o a -> Either (Automaton p v o a) (Automaton p i o a)
beforeStep = p
-> Automaton p i o a
-> Either (Automaton p v o a) (Automaton p i o a)
forall {p} {i} {o} {a} {i} {o} {a}.
Monoid p =>
p
-> Automaton p i o a
-> Either (Automaton p i o a) (Automaton p i o a)
go p
forall a. Monoid a => a
mempty where
  go :: p
-> Automaton p i o a
-> Either (Automaton p i o a) (Automaton p i o a)
go p
_ (Result a
_) = Automaton p i o a -> Either (Automaton p i o a) (Automaton p i o a)
forall a b. a -> Either a b
Left (([String] -> [String]) -> Automaton p i o a
forall p i o a. ([String] -> [String]) -> Automaton p i o a
Failed [String] -> [String]
forall a. a -> a
id)
  go p
_ r :: Automaton p i o a
r@(Ready i -> Automaton p i o a
_ [String] -> [String]
_) = Automaton p i o a -> Either (Automaton p i o a) (Automaton p i o a)
forall a b. b -> Either a b
Right Automaton p i o a
r
  go p
_ (Failed [String] -> [String]
f) = Automaton p i o a -> Either (Automaton p i o a) (Automaton p i o a)
forall a b. a -> Either a b
Left (Automaton p i o a
 -> Either (Automaton p i o a) (Automaton p i o a))
-> Automaton p i o a
-> Either (Automaton p i o a) (Automaton p i o a)
forall a b. (a -> b) -> a -> b
$ ([String] -> [String]) -> Automaton p i o a
forall p i o a. ([String] -> [String]) -> Automaton p i o a
Failed [String] -> [String]
f 
  go p
p (Automaton p i o a
a :+++ Automaton p i o a
b) = case (p
-> Automaton p i o a
-> Either (Automaton p i o a) (Automaton p i o a)
go p
p Automaton p i o a
a, p
-> Automaton p i o a
-> Either (Automaton p i o a) (Automaton p i o a)
go p
p Automaton p i o a
b) of
    (Right Automaton p i o a
a', Right Automaton p i o a
b') -> Automaton p i o a -> Either (Automaton p i o a) (Automaton p i o a)
forall a b. b -> Either a b
Right (Automaton p i o a
 -> Either (Automaton p i o a) (Automaton p i o a))
-> Automaton p i o a
-> Either (Automaton p i o a) (Automaton p i o a)
forall a b. (a -> b) -> a -> b
$ Automaton p i o a -> Automaton p i o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (Automaton p i o a -> Automaton p i o a)
-> Automaton p i o a -> Automaton p i o a
forall a b. (a -> b) -> a -> b
$ Automaton p i o a
a' Automaton p i o a -> Automaton p i o a -> Automaton p i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton p i o a
b'
    (a' :: Either (Automaton p i o a) (Automaton p i o a)
a'@(Right Automaton p i o a
_), Left Automaton p i o a
_) -> Either (Automaton p i o a) (Automaton p i o a)
a'
    (Left Automaton p i o a
_, b' :: Either (Automaton p i o a) (Automaton p i o a)
b'@(Right Automaton p i o a
_)) -> Either (Automaton p i o a) (Automaton p i o a)
b'
    (Left Automaton p i o a
a', Left Automaton p i o a
b') -> Automaton p i o a -> Either (Automaton p i o a) (Automaton p i o a)
forall a b. a -> Either a b
Left (Automaton p i o a
 -> Either (Automaton p i o a) (Automaton p i o a))
-> Automaton p i o a
-> Either (Automaton p i o a) (Automaton p i o a)
forall a b. (a -> b) -> a -> b
$ Automaton p i o a -> Automaton p i o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (Automaton p i o a -> Automaton p i o a)
-> Automaton p i o a -> Automaton p i o a
forall a b. (a -> b) -> a -> b
$ Automaton p i o a
a' Automaton p i o a -> Automaton p i o a -> Automaton p i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton p i o a
b'
  go p
p (Yield o
o Automaton p i o a
r) = case p
-> Automaton p i o a
-> Either (Automaton p i o a) (Automaton p i o a)
go p
p Automaton p i o a
r of
    r' :: Either (Automaton p i o a) (Automaton p i o a)
r'@(Left Automaton p i o a
_) -> Either (Automaton p i o a) (Automaton p i o a)
r'
    Right Automaton p i o a
r' -> Automaton p i o a -> Either (Automaton p i o a) (Automaton p i o a)
forall a b. b -> Either a b
Right (Automaton p i o a -> Automaton p i o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (Automaton p i o a -> Automaton p i o a)
-> Automaton p i o a -> Automaton p i o a
forall a b. (a -> b) -> a -> b
$ o -> Automaton p i o a -> Automaton p i o a
forall p i o a. o -> Automaton p i o a -> Automaton p i o a
Yield o
o Automaton p i o a
r')
  go p
p0 (Count p
p1 Automaton p i o a
r) = let p :: p
p = p -> p -> p
forall a. Monoid a => a -> a -> a
mappend p
p0 p
p1 in case p
-> Automaton p i o a
-> Either (Automaton p i o a) (Automaton p i o a)
go p
p Automaton p i o a
r of
    Left Automaton p i o a
r' -> Automaton p i o a -> Either (Automaton p i o a) (Automaton p i o a)
forall a b. a -> Either a b
Left (Automaton p i o a
 -> Either (Automaton p i o a) (Automaton p i o a))
-> Automaton p i o a
-> Either (Automaton p i o a) (Automaton p i o a)
forall a b. (a -> b) -> a -> b
$ Automaton p i o a -> Automaton p i o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (Automaton p i o a -> Automaton p i o a)
-> Automaton p i o a -> Automaton p i o a
forall a b. (a -> b) -> a -> b
$ p -> Automaton p i o a -> Automaton p i o a
forall p i o a. p -> Automaton p i o a -> Automaton p i o a
Count p
p1 Automaton p i o a
r'
    Right Automaton p i o a
r' -> Automaton p i o a -> Either (Automaton p i o a) (Automaton p i o a)
forall a b. b -> Either a b
Right (Automaton p i o a
 -> Either (Automaton p i o a) (Automaton p i o a))
-> Automaton p i o a
-> Either (Automaton p i o a) (Automaton p i o a)
forall a b. (a -> b) -> a -> b
$ Automaton p i o a -> Automaton p i o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (Automaton p i o a -> Automaton p i o a)
-> Automaton p i o a -> Automaton p i o a
forall a b. (a -> b) -> a -> b
$ p -> Automaton p i o a -> Automaton p i o a
forall p i o a. p -> Automaton p i o a -> Automaton p i o a
Count p
p1 Automaton p i o a
r'
  go p
p (GetCount p -> Automaton p i o a
n) = p
-> Automaton p i o a
-> Either (Automaton p i o a) (Automaton p i o a)
go p
p (p -> Automaton p i o a
n p
p)

-- Apoligies for code duplication
beforeStep' :: (Monoid p) => Automaton p i o a ->
  Either (Automaton p v o a) (Automaton p i o a)
beforeStep' :: forall p i o a v.
Monoid p =>
Automaton p i o a -> Either (Automaton p v o a) (Automaton p i o a)
beforeStep' = ((Bool, Automaton p i o a, Automaton p i o a) -> Automaton p i o a)
-> Either
     (Automaton p v o a) (Bool, Automaton p i o a, Automaton p i o a)
-> Either (Automaton p v o a) (Automaton p i o a)
forall a b.
(a -> b)
-> Either (Automaton p v o a) a -> Either (Automaton p v o a) b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(Bool
s,Automaton p i o a
a,Automaton p i o a
b) -> if Bool
s then Automaton p i o a
a else Automaton p i o a
b) (Either
   (Automaton p v o a) (Bool, Automaton p i o a, Automaton p i o a)
 -> Either (Automaton p v o a) (Automaton p i o a))
-> (Automaton p i o a
    -> Either
         (Automaton p v o a) (Bool, Automaton p i o a, Automaton p i o a))
-> Automaton p i o a
-> Either (Automaton p v o a) (Automaton p i o a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Automaton p i o a
-> Either
     (Automaton p v o a) (Bool, Automaton p i o a, Automaton p i o a)
forall {p} {i} {o} {a} {i} {a}.
Monoid p =>
Automaton p i o a
-> Either
     (Automaton p i o a) (Bool, Automaton p i o a, Automaton p i o a)
go where
  go :: Automaton p i o a
-> Either
     (Automaton p i o a) (Bool, Automaton p i o a, Automaton p i o a)
go (Result a
_) = Automaton p i o a
-> Either
     (Automaton p i o a) (Bool, Automaton p i o a, Automaton p i o a)
forall a b. a -> Either a b
Left (([String] -> [String]) -> Automaton p i o a
forall p i o a. ([String] -> [String]) -> Automaton p i o a
Failed [String] -> [String]
forall a. a -> a
id)
  go r :: Automaton p i o a
r@(Ready i -> Automaton p i o a
_ [String] -> [String]
_) = (Bool, Automaton p i o a, Automaton p i o a)
-> Either
     (Automaton p i o a) (Bool, Automaton p i o a, Automaton p i o a)
forall a b. b -> Either a b
Right (Bool
True,Automaton p i o a
r,Automaton p i o a
r)
  go (Failed [String] -> [String]
e) = Automaton p i o a
-> Either
     (Automaton p i o a) (Bool, Automaton p i o a, Automaton p i o a)
forall a b. a -> Either a b
Left (([String] -> [String]) -> Automaton p i o a
forall p i o a. ([String] -> [String]) -> Automaton p i o a
Failed [String] -> [String]
e)
  -- When we reach 'GetCount': we don't know whether or not it's hiding a 'Ready'.
  -- It can't be safely removed, and unlike finding 'Ready' it doesn't
  -- indicate that errors be safely removed.
  go (Automaton p i o a
a :+++ Automaton p i o a
b) = case (Automaton p i o a
-> Either
     (Automaton p i o a) (Bool, Automaton p i o a, Automaton p i o a)
go Automaton p i o a
a, Automaton p i o a
-> Either
     (Automaton p i o a) (Bool, Automaton p i o a, Automaton p i o a)
go Automaton p i o a
b) of
    (Left Automaton p i o a
a', Left Automaton p i o a
b') -> Automaton p i o a
-> Either
     (Automaton p i o a) (Bool, Automaton p i o a, Automaton p i o a)
forall a b. a -> Either a b
Left (Automaton p i o a -> Automaton p i o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (Automaton p i o a
a' Automaton p i o a -> Automaton p i o a -> Automaton p i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton p i o a
b'))
    -- You could do without 'unsafeCoerce' here if you used ImpredicativeTypes:
    -- but it wouldn't be worth it.
    (Right (Bool
sa,Automaton p i o a
a1,Automaton p i o a
a2), Left Automaton p i o a
b') -> (Bool, Automaton p i o a, Automaton p i o a)
-> Either
     (Automaton p i o a) (Bool, Automaton p i o a, Automaton p i o a)
forall a b. b -> Either a b
Right (Bool
sa,Automaton p i o a
a1,Automaton p i o a -> Automaton p i o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (Automaton p i o a
a2 Automaton p i o a -> Automaton p i o a -> Automaton p i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton p i o a -> Automaton p i o a
forall a b. a -> b
unsafeCoerce Automaton p i o a
b'))
    (Left Automaton p i o a
a', Right (Bool
sb,Automaton p i o a
b1,Automaton p i o a
b2)) -> (Bool, Automaton p i o a, Automaton p i o a)
-> Either
     (Automaton p i o a) (Bool, Automaton p i o a, Automaton p i o a)
forall a b. b -> Either a b
Right (Bool
sb,Automaton p i o a
b1,Automaton p i o a -> Automaton p i o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (Automaton p i o a -> Automaton p i o a
forall a b. a -> b
unsafeCoerce Automaton p i o a
a' Automaton p i o a -> Automaton p i o a -> Automaton p i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton p i o a
b2))
    (Right (Bool
sa,Automaton p i o a
a1,Automaton p i o a
a2), Right (Bool
sb,Automaton p i o a
b1,Automaton p i o a
b2)) ->
      (Bool, Automaton p i o a, Automaton p i o a)
-> Either
     (Automaton p i o a) (Bool, Automaton p i o a, Automaton p i o a)
forall a b. b -> Either a b
Right (Bool
sa Bool -> Bool -> Bool
|| Bool
sb, Automaton p i o a -> Automaton p i o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (Automaton p i o a
a1 Automaton p i o a -> Automaton p i o a -> Automaton p i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton p i o a
b1), Automaton p i o a -> Automaton p i o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (Automaton p i o a
a2 Automaton p i o a -> Automaton p i o a -> Automaton p i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton p i o a
b2))
  go (Yield o
o Automaton p i o a
r) = case Automaton p i o a
-> Either
     (Automaton p i o a) (Bool, Automaton p i o a, Automaton p i o a)
go Automaton p i o a
r of
    Left Automaton p i o a
r' -> Automaton p i o a
-> Either
     (Automaton p i o a) (Bool, Automaton p i o a, Automaton p i o a)
forall a b. a -> Either a b
Left (o -> Automaton p i o a -> Automaton p i o a
forall p i o a. o -> Automaton p i o a -> Automaton p i o a
Yield o
o Automaton p i o a
r')
    Right (Bool
s,Automaton p i o a
r1,Automaton p i o a
r2) -> (Bool, Automaton p i o a, Automaton p i o a)
-> Either
     (Automaton p i o a) (Bool, Automaton p i o a, Automaton p i o a)
forall a b. b -> Either a b
Right (Bool
s, o -> Automaton p i o a -> Automaton p i o a
forall p i o a. o -> Automaton p i o a -> Automaton p i o a
Yield o
o Automaton p i o a
r1, o -> Automaton p i o a -> Automaton p i o a
forall p i o a. o -> Automaton p i o a -> Automaton p i o a
Yield o
o Automaton p i o a
r2)
  go (Count p
p Automaton p i o a
r) = case Automaton p i o a
-> Either
     (Automaton p i o a) (Bool, Automaton p i o a, Automaton p i o a)
go Automaton p i o a
r of
    Left Automaton p i o a
r' -> Automaton p i o a
-> Either
     (Automaton p i o a) (Bool, Automaton p i o a, Automaton p i o a)
forall a b. a -> Either a b
Left (p -> Automaton p i o a -> Automaton p i o a
forall p i o a. p -> Automaton p i o a -> Automaton p i o a
Count p
p Automaton p i o a
r')
    Right (Bool
s,Automaton p i o a
r1,Automaton p i o a
r2) -> (Bool, Automaton p i o a, Automaton p i o a)
-> Either
     (Automaton p i o a) (Bool, Automaton p i o a, Automaton p i o a)
forall a b. b -> Either a b
Right (Bool
s, p -> Automaton p i o a -> Automaton p i o a
forall p i o a. p -> Automaton p i o a -> Automaton p i o a
Count p
p Automaton p i o a
r1, p -> Automaton p i o a -> Automaton p i o a
forall p i o a. p -> Automaton p i o a -> Automaton p i o a
Count p
p Automaton p i o a
r2)
  go a :: Automaton p i o a
a@(GetCount p -> Automaton p i o a
_) = (Bool, Automaton p i o a, Automaton p i o a)
-> Either
     (Automaton p i o a) (Bool, Automaton p i o a, Automaton p i o a)
forall a b. b -> Either a b
Right (Bool
False,Automaton p i o a
a,Automaton p i o a
a)

-- | Pass one input to an automaton
step :: (Monoid p) => Automaton p i o a -> i -> Automaton p i o a
step :: forall p i o a.
Monoid p =>
Automaton p i o a -> i -> Automaton p i o a
step Automaton p i o a
a' i
i = p -> Automaton p i o a -> Automaton p i o a
forall {a} {o} {a}.
Monoid a =>
a -> Automaton a i o a -> Automaton a i o a
go p
forall a. Monoid a => a
mempty Automaton p i o a
a' where
  go :: a -> Automaton a i o a -> Automaton a i o a
go a
_ (Result a
_) = ([String] -> [String]) -> Automaton a i o a
forall p i o a. ([String] -> [String]) -> Automaton p i o a
Failed [String] -> [String]
forall a. a -> a
id
  go a
_ (Ready i -> Automaton a i o a
n [String] -> [String]
_) = i -> Automaton a i o a
n i
i
  go a
_ (Failed [String] -> [String]
e) = ([String] -> [String]) -> Automaton a i o a
forall p i o a. ([String] -> [String]) -> Automaton p i o a
Failed [String] -> [String]
e
  go a
p (Automaton a i o a
a :+++ Automaton a i o a
b) = Automaton a i o a -> Automaton a i o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (a -> Automaton a i o a -> Automaton a i o a
go a
p Automaton a i o a
a Automaton a i o a -> Automaton a i o a -> Automaton a i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ a -> Automaton a i o a -> Automaton a i o a
go a
p Automaton a i o a
b)
  go a
p (Yield o
o Automaton a i o a
r) = Automaton a i o a -> Automaton a i o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (o -> Automaton a i o a -> Automaton a i o a
forall p i o a. o -> Automaton p i o a -> Automaton p i o a
Yield o
o (a -> Automaton a i o a -> Automaton a i o a
go a
p Automaton a i o a
r))
  go a
p0 (Count a
p1 Automaton a i o a
r) = let
    p :: a
p = a -> a -> a
forall a. Monoid a => a -> a -> a
mappend a
p0 a
p1
    in a
p a -> Automaton a i o a -> Automaton a i o a
forall a b. a -> b -> b
`seq` Automaton a i o a -> Automaton a i o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (a -> Automaton a i o a -> Automaton a i o a
forall p i o a. p -> Automaton p i o a -> Automaton p i o a
Count a
p1 (a -> Automaton a i o a -> Automaton a i o a
go a
p Automaton a i o a
r))
  go a
p (GetCount a -> Automaton a i o a
n) = a -> Automaton a i o a -> Automaton a i o a
go a
p (a -> Automaton a i o a
n a
p)

step' :: (Monoid p) => Automaton p i o a -> i -> Automaton p i o a
step' :: forall p i o a.
Monoid p =>
Automaton p i o a -> i -> Automaton p i o a
step' Automaton p i o a
a' i
i = Automaton p i o a -> Automaton p i o a
forall {p} {o} {a}.
Monoid p =>
Automaton p i o a -> Automaton p i o a
go Automaton p i o a
a' where
  go :: Automaton p i o a -> Automaton p i o a
go (Result a
_) = ([String] -> [String]) -> Automaton p i o a
forall p i o a. ([String] -> [String]) -> Automaton p i o a
Failed [String] -> [String]
forall a. a -> a
id
  go (Ready i -> Automaton p i o a
n [String] -> [String]
_) = i -> Automaton p i o a
n i
i
  go (Failed [String] -> [String]
e) = ([String] -> [String]) -> Automaton p i o a
forall p i o a. ([String] -> [String]) -> Automaton p i o a
Failed [String] -> [String]
e
  go (Automaton p i o a
a :+++ Automaton p i o a
b) = Automaton p i o a -> Automaton p i o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (Automaton p i o a -> Automaton p i o a
go Automaton p i o a
a Automaton p i o a -> Automaton p i o a -> Automaton p i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton p i o a -> Automaton p i o a
go Automaton p i o a
b)
  go (Yield o
o Automaton p i o a
r) = Automaton p i o a -> Automaton p i o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (o -> Automaton p i o a -> Automaton p i o a
forall p i o a. o -> Automaton p i o a -> Automaton p i o a
Yield o
o (Automaton p i o a -> Automaton p i o a
go Automaton p i o a
r))
  go (Count p
p Automaton p i o a
r) = Automaton p i o a -> Automaton p i o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (p -> Automaton p i o a -> Automaton p i o a
forall p i o a. p -> Automaton p i o a -> Automaton p i o a
Count p
p (Automaton p i o a -> Automaton p i o a
go Automaton p i o a
r))
  go (GetCount p -> Automaton p i o a
n) = (p -> Automaton p i o a) -> Automaton p i o a
forall p i o a. (p -> Automaton p i o a) -> Automaton p i o a
GetCount ((Automaton p i o a -> Automaton p i o a)
-> (p -> Automaton p i o a) -> p -> Automaton p i o a
forall a b. (a -> b) -> (p -> a) -> p -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Automaton p i o a -> Automaton p i o a
go p -> Automaton p i o a
n)

-- | Take either counters with errors or a list of possible results from an
-- automaton.
extract :: (Monoid p) => p -> Automaton p i o a -> Either [(p,[String])] [a]
extract :: forall p i o a.
Monoid p =>
p -> Automaton p i o a -> Either [(p, [String])] [a]
extract p
p' Automaton p i o a
a = case p
-> Automaton p i o a
-> Either
     ([(p, [String] -> [String])] -> [(p, [String] -> [String])])
     ([a] -> [a])
forall {a} {i} {o} {a}.
Monoid a =>
a
-> Automaton a i o a
-> Either
     ([(a, [String] -> [String])] -> [(a, [String] -> [String])])
     ([a] -> [a])
go p
p' Automaton p i o a
a of
  Left [(p, [String] -> [String])] -> [(p, [String] -> [String])]
e -> [(p, [String])] -> Either [(p, [String])] [a]
forall a b. a -> Either a b
Left ([(p, [String])] -> Either [(p, [String])] [a])
-> [(p, [String])] -> Either [(p, [String])] [a]
forall a b. (a -> b) -> a -> b
$ ((p, [String] -> [String]) -> (p, [String]))
-> [(p, [String] -> [String])] -> [(p, [String])]
forall a b. (a -> b) -> [a] -> [b]
map (\(p
p,[String] -> [String]
e') -> (p
p, [String] -> [String]
e' [])) ([(p, [String] -> [String])] -> [(p, [String] -> [String])]
e [])
  Right [a] -> [a]
r -> [a] -> Either [(p, [String])] [a]
forall a b. b -> Either a b
Right ([a] -> Either [(p, [String])] [a])
-> [a] -> Either [(p, [String])] [a]
forall a b. (a -> b) -> a -> b
$ [a] -> [a]
r []
 where
  go :: a
-> Automaton a i o a
-> Either
     ([(a, [String] -> [String])] -> [(a, [String] -> [String])])
     ([a] -> [a])
go a
_ (Result a
z) = ([a] -> [a])
-> Either
     ([(a, [String] -> [String])] -> [(a, [String] -> [String])])
     ([a] -> [a])
forall a b. b -> Either a b
Right (a
za -> [a] -> [a]
forall a. a -> [a] -> [a]
:)
  go a
p (Ready i -> Automaton a i o a
_ [String] -> [String]
e) = ([(a, [String] -> [String])] -> [(a, [String] -> [String])])
-> Either
     ([(a, [String] -> [String])] -> [(a, [String] -> [String])])
     ([a] -> [a])
forall a b. a -> Either a b
Left ((a
p,[String] -> [String]
e)(a, [String] -> [String])
-> [(a, [String] -> [String])] -> [(a, [String] -> [String])]
forall a. a -> [a] -> [a]
:)
  go a
p (Failed [String] -> [String]
e) = ([(a, [String] -> [String])] -> [(a, [String] -> [String])])
-> Either
     ([(a, [String] -> [String])] -> [(a, [String] -> [String])])
     ([a] -> [a])
forall a b. a -> Either a b
Left ((a
p,[String] -> [String]
e)(a, [String] -> [String])
-> [(a, [String] -> [String])] -> [(a, [String] -> [String])]
forall a. a -> [a] -> [a]
:)
  go a
p (Automaton a i o a
a :+++ Automaton a i o a
b) = case (a
-> Automaton a i o a
-> Either
     ([(a, [String] -> [String])] -> [(a, [String] -> [String])])
     ([a] -> [a])
go a
p Automaton a i o a
a, a
-> Automaton a i o a
-> Either
     ([(a, [String] -> [String])] -> [(a, [String] -> [String])])
     ([a] -> [a])
go a
p Automaton a i o a
b) of
    (Right [a] -> [a]
a', Right [a] -> [a]
b') -> ([a] -> [a])
-> Either
     ([(a, [String] -> [String])] -> [(a, [String] -> [String])])
     ([a] -> [a])
forall a b. b -> Either a b
Right ([a] -> [a]
a' ([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [a]
b')
    (a' :: Either
  ([(a, [String] -> [String])] -> [(a, [String] -> [String])])
  ([a] -> [a])
a'@(Right [a] -> [a]
_), Left [(a, [String] -> [String])] -> [(a, [String] -> [String])]
_) -> Either
  ([(a, [String] -> [String])] -> [(a, [String] -> [String])])
  ([a] -> [a])
a'
    (Left [(a, [String] -> [String])] -> [(a, [String] -> [String])]
_, b' :: Either
  ([(a, [String] -> [String])] -> [(a, [String] -> [String])])
  ([a] -> [a])
b'@(Right [a] -> [a]
_)) -> Either
  ([(a, [String] -> [String])] -> [(a, [String] -> [String])])
  ([a] -> [a])
b'
    (Left [(a, [String] -> [String])] -> [(a, [String] -> [String])]
a', Left [(a, [String] -> [String])] -> [(a, [String] -> [String])]
b') -> ([(a, [String] -> [String])] -> [(a, [String] -> [String])])
-> Either
     ([(a, [String] -> [String])] -> [(a, [String] -> [String])])
     ([a] -> [a])
forall a b. a -> Either a b
Left ([(a, [String] -> [String])] -> [(a, [String] -> [String])]
a' ([(a, [String] -> [String])] -> [(a, [String] -> [String])])
-> ([(a, [String] -> [String])] -> [(a, [String] -> [String])])
-> [(a, [String] -> [String])]
-> [(a, [String] -> [String])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(a, [String] -> [String])] -> [(a, [String] -> [String])]
b')
  go a
p (Yield o
_ Automaton a i o a
r) = a
-> Automaton a i o a
-> Either
     ([(a, [String] -> [String])] -> [(a, [String] -> [String])])
     ([a] -> [a])
go a
p Automaton a i o a
r
  go a
p (Count a
i Automaton a i o a
r) = let
    p' :: a
p' = a -> a -> a
forall a. Monoid a => a -> a -> a
mappend a
p a
i
    in a
p' a
-> Either
     ([(a, [String] -> [String])] -> [(a, [String] -> [String])])
     ([a] -> [a])
-> Either
     ([(a, [String] -> [String])] -> [(a, [String] -> [String])])
     ([a] -> [a])
forall a b. a -> b -> b
`seq` a
-> Automaton a i o a
-> Either
     ([(a, [String] -> [String])] -> [(a, [String] -> [String])])
     ([a] -> [a])
go a
p' Automaton a i o a
r
  go a
p (GetCount a -> Automaton a i o a
n) = a
-> Automaton a i o a
-> Either
     ([(a, [String] -> [String])] -> [(a, [String] -> [String])])
     ([a] -> [a])
go a
p (a -> Automaton a i o a
n a
p)

-- | Create a 'ReadS' like value from a Phaser type. If the input
-- type is 'Char', the result will be 'ReadS'
toReadS :: (PhaserType s, Monoid p) =>
  s p i o a -> [i] -> [(a,[i])]
toReadS :: forall (s :: * -> * -> * -> * -> *) p i o a.
(PhaserType s, Monoid p) =>
s p i o a -> [i] -> [(a, [i])]
toReadS s p i o a
a [i]
i = case p
-> Phase p i o (a, [i]) -> [i] -> Either [(p, [String])] [(a, [i])]
forall p (s :: * -> * -> * -> * -> *) i o a.
(Monoid p, PhaserType s) =>
p -> s p i o a -> [i] -> Either [(p, [String])] [a]
parse_ p
forall a. Monoid a => a
mempty ((,) (a -> [i] -> (a, [i]))
-> Phase p i o a -> Phase p i o ([i] -> (a, [i]))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s p i o a -> Phase p i o a
forall p i o a. Monoid p => s p i o a -> Phase p i o a
forall (s :: * -> * -> * -> * -> *) p i o a.
(PhaserType s, Monoid p) =>
s p i o a -> Phase p i o a
toPhase s p i o a
a Phase p i o ([i] -> (a, [i]))
-> Phase p i o [i] -> Phase p i o (a, [i])
forall a b. Phase p i o (a -> b) -> Phase p i o a -> Phase p i o b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Phase p i o i -> Phase p i o [i]
forall a. Phase p i o a -> Phase p i o [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many Phase p i o i
forall p i o. Phase p i o i
get) [i]
i of
  Right [(a, [i])]
r -> [(a, [i])]
r
  Left [(p, [String])]
_ -> []

-- | Pass a list of input values to an 'Automaton'
run :: (Monoid p) => Automaton p i o a -> [i] -> Automaton p i o a
run :: forall p i o a.
Monoid p =>
Automaton p i o a -> [i] -> Automaton p i o a
run = Automaton p i o a -> [i] -> Automaton p i o a
forall p i o a.
Monoid p =>
Automaton p i o a -> [i] -> Automaton p i o a
go where
  go :: Automaton p i o a -> [i] -> Automaton p i o a
go Automaton p i o a
a [] = Automaton p i o a
a
  go Automaton p i o a
a (i
i:[i]
r) = case Automaton p i o a -> Either (Automaton p i o a) (Automaton p i o a)
forall p i o a v.
Monoid p =>
Automaton p i o a -> Either (Automaton p v o a) (Automaton p i o a)
beforeStep Automaton p i o a
a of
    Left Automaton p i o a
a' -> Automaton p i o a
a'
    Right Automaton p i o a
a' -> Automaton p i o a -> [i] -> Automaton p i o a
go (Automaton p i o a -> i -> Automaton p i o a
forall p i o a.
Monoid p =>
Automaton p i o a -> i -> Automaton p i o a
step Automaton p i o a
a' i
i) [i]
r

run' :: (Monoid p) => Automaton p i o a -> [i] -> Automaton p i o a
run' :: forall p i o a.
Monoid p =>
Automaton p i o a -> [i] -> Automaton p i o a
run' = Automaton p i o a -> [i] -> Automaton p i o a
forall p i o a.
Monoid p =>
Automaton p i o a -> [i] -> Automaton p i o a
go where
  go :: Automaton p i o a -> [i] -> Automaton p i o a
go Automaton p i o a
a [] = Automaton p i o a
a
  go Automaton p i o a
a (i
i:[i]
r) = case Automaton p i o a -> Either (Automaton p i o a) (Automaton p i o a)
forall p i o a v.
Monoid p =>
Automaton p i o a -> Either (Automaton p v o a) (Automaton p i o a)
beforeStep' Automaton p i o a
a of
    Left Automaton p i o a
a' -> Automaton p i o a
a'
    Right Automaton p i o a
a' -> Automaton p i o a -> [i] -> Automaton p i o a
go (Automaton p i o a -> i -> Automaton p i o a
forall p i o a.
Monoid p =>
Automaton p i o a -> i -> Automaton p i o a
step' Automaton p i o a
a' i
i) [i]
r

-- | Use a 'Phase' value similarly to a parser.
parse_ :: (Monoid p, PhaserType s) => p -> s p i o a -> [i] -> Either [(p,[String])] [a]
parse_ :: forall p (s :: * -> * -> * -> * -> *) i o a.
(Monoid p, PhaserType s) =>
p -> s p i o a -> [i] -> Either [(p, [String])] [a]
parse_ p
p s p i o a
a [i]
i = p -> Automaton p i o a -> Either [(p, [String])] [a]
forall p i o a.
Monoid p =>
p -> Automaton p i o a -> Either [(p, [String])] [a]
extract p
forall a. Monoid a => a
mempty (Automaton p i o a -> Either [(p, [String])] [a])
-> Automaton p i o a -> Either [(p, [String])] [a]
forall a b. (a -> b) -> a -> b
$ Automaton p i o a -> [i] -> Automaton p i o a
forall p i o a.
Monoid p =>
Automaton p i o a -> [i] -> Automaton p i o a
run (p -> Automaton p i o a -> Automaton p i o a
forall p i o a. p -> Automaton p i o a -> Automaton p i o a
Count p
p (Automaton p i o a -> Automaton p i o a)
-> Automaton p i o a -> Automaton p i o a
forall a b. (a -> b) -> a -> b
$ s p i o a -> Automaton p i o a
forall p i o a. Monoid p => s p i o a -> Automaton p i o a
forall (s :: * -> * -> * -> * -> *) p i o a.
(PhaserType s, Monoid p) =>
s p i o a -> Automaton p i o a
toAutomaton s p i o a
a) [i]
i

-- | Use a 'Phase' as a parser, but consuming a single input instead of a list
parse1_ :: (Monoid p, PhaserType s) => p -> s p i o a -> i -> Either [(p,[String])] [a]
parse1_ :: forall p (s :: * -> * -> * -> * -> *) i o a.
(Monoid p, PhaserType s) =>
p -> s p i o a -> i -> Either [(p, [String])] [a]
parse1_ p
p s p i o a
a i
i = p -> Automaton p i o a -> Either [(p, [String])] [a]
forall p i o a.
Monoid p =>
p -> Automaton p i o a -> Either [(p, [String])] [a]
extract p
forall a. Monoid a => a
mempty (Automaton p i o a -> Either [(p, [String])] [a])
-> Automaton p i o a -> Either [(p, [String])] [a]
forall a b. (a -> b) -> a -> b
$ Automaton p i o a -> i -> Automaton p i o a
forall p i o a.
Monoid p =>
Automaton p i o a -> i -> Automaton p i o a
step (p -> Automaton p i o a -> Automaton p i o a
forall p i o a. p -> Automaton p i o a -> Automaton p i o a
Count p
p (Automaton p i o a -> Automaton p i o a)
-> Automaton p i o a -> Automaton p i o a
forall a b. (a -> b) -> a -> b
$ s p i o a -> Automaton p i o a
forall p i o a. Monoid p => s p i o a -> Automaton p i o a
forall (s :: * -> * -> * -> * -> *) p i o a.
(PhaserType s, Monoid p) =>
s p i o a -> Automaton p i o a
toAutomaton s p i o a
a) i
i

-- | Decompose an 'Automaton' into its component options.
options :: Monoid p => Automaton p i o a -> [Automaton p i o a]
options :: forall p i o a.
Monoid p =>
Automaton p i o a -> [Automaton p i o a]
options = (([Automaton p i o a] -> [Automaton p i o a])
-> [Automaton p i o a] -> [Automaton p i o a]
forall a b. (a -> b) -> a -> b
$ []) (([Automaton p i o a] -> [Automaton p i o a])
 -> [Automaton p i o a])
-> (Automaton p i o a
    -> [Automaton p i o a] -> [Automaton p i o a])
-> Automaton p i o a
-> [Automaton p i o a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Automaton p i o a -> [Automaton p i o a] -> [Automaton p i o a]
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> [Automaton a i o a] -> [Automaton a i o a]
go where
  go :: Automaton a i o a -> [Automaton a i o a] -> [Automaton a i o a]
go (Automaton a i o a
a :+++ Automaton a i o a
b) = Automaton a i o a -> [Automaton a i o a] -> [Automaton a i o a]
go Automaton a i o a
a ([Automaton a i o a] -> [Automaton a i o a])
-> ([Automaton a i o a] -> [Automaton a i o a])
-> [Automaton a i o a]
-> [Automaton a i o a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Automaton a i o a -> [Automaton a i o a] -> [Automaton a i o a]
go Automaton a i o a
b
  go (Yield o
o Automaton a i o a
r) = ((Automaton a i o a -> Automaton a i o a)
-> [Automaton a i o a] -> [Automaton a i o a]
forall a b. (a -> b) -> [a] -> [b]
map (Automaton a i o a -> Automaton a i o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (Automaton a i o a -> Automaton a i o a)
-> (Automaton a i o a -> Automaton a i o a)
-> Automaton a i o a
-> Automaton a i o a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. o -> Automaton a i o a -> Automaton a i o a
forall p i o a. o -> Automaton p i o a -> Automaton p i o a
Yield o
o) (Automaton a i o a -> [Automaton a i o a] -> [Automaton a i o a]
go Automaton a i o a
r []) [Automaton a i o a] -> [Automaton a i o a] -> [Automaton a i o a]
forall a. [a] -> [a] -> [a]
++)
  go (Count a
p Automaton a i o a
r) = ((Automaton a i o a -> Automaton a i o a)
-> [Automaton a i o a] -> [Automaton a i o a]
forall a b. (a -> b) -> [a] -> [b]
map (Automaton a i o a -> Automaton a i o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (Automaton a i o a -> Automaton a i o a)
-> (Automaton a i o a -> Automaton a i o a)
-> Automaton a i o a
-> Automaton a i o a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Automaton a i o a -> Automaton a i o a
forall p i o a. p -> Automaton p i o a -> Automaton p i o a
Count a
p) (Automaton a i o a -> [Automaton a i o a] -> [Automaton a i o a]
go Automaton a i o a
r []) [Automaton a i o a] -> [Automaton a i o a] -> [Automaton a i o a]
forall a. [a] -> [a] -> [a]
++)
  go Automaton a i o a
a = (Automaton a i o a
a Automaton a i o a -> [Automaton a i o a] -> [Automaton a i o a]
forall a. a -> [a] -> [a]
:)

-- | Separate unconditional counter modifiers from an automaton. The removal
-- is visible to 'getCount'
readCount :: (Monoid p) => Automaton p i o a -> (p, Automaton p i o a)
readCount :: forall p i o a.
Monoid p =>
Automaton p i o a -> (p, Automaton p i o a)
readCount = Automaton p i o a -> (p, Automaton p i o a)
forall p i o a.
Monoid p =>
Automaton p i o a -> (p, Automaton p i o a)
go where
  go :: Automaton a i o a -> (a, Automaton a i o a)
go (Count a
p0 Automaton a i o a
r) = let
    (a
p1, Automaton a i o a
r') = Automaton a i o a -> (a, Automaton a i o a)
go Automaton a i o a
r
    p' :: a
p' = a
p0 a -> a -> a
forall a. Monoid a => a -> a -> a
`mappend` a
p1
    in a
p' a -> (a, Automaton a i o a) -> (a, Automaton a i o a)
forall a b. a -> b -> b
`seq` (a
p', Automaton a i o a
r')
  go (Yield o
o Automaton a i o a
r) = let
    (a
p, Automaton a i o a
r') = Automaton a i o a -> (a, Automaton a i o a)
go Automaton a i o a
r
    in (a
p, Automaton a i o a -> Automaton a i o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (Automaton a i o a -> Automaton a i o a)
-> Automaton a i o a -> Automaton a i o a
forall a b. (a -> b) -> a -> b
$ o -> Automaton a i o a -> Automaton a i o a
forall p i o a. o -> Automaton p i o a -> Automaton p i o a
Yield o
o Automaton a i o a
r')
  go Automaton a i o a
a = (a
forall a. Monoid a => a
mempty, Automaton a i o a
a)

-- | Separate the values unconditionally yielded by an automaton
outputs :: (Monoid p) => Automaton p i o a -> ([o], Automaton p i o a)
outputs :: forall p i o a.
Monoid p =>
Automaton p i o a -> ([o], Automaton p i o a)
outputs = Automaton p i o a -> ([o], Automaton p i o a)
forall p i o a.
Monoid p =>
Automaton p i o a -> ([o], Automaton p i o a)
go where
  go :: Automaton a i o a -> ([o], Automaton a i o a)
go (Yield o
o Automaton a i o a
r) = let
    ([o]
o', Automaton a i o a
r') = Automaton a i o a -> ([o], Automaton a i o a)
go Automaton a i o a
r
    in (o
oo -> [o] -> [o]
forall a. a -> [a] -> [a]
:[o]
o', Automaton a i o a
r')
  go (Count a
p Automaton a i o a
r) = let
    ([o]
o, Automaton a i o a
r') = Automaton a i o a -> ([o], Automaton a i o a)
go Automaton a i o a
r
    in ([o]
o, Automaton a i o a -> Automaton a i o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (Automaton a i o a -> Automaton a i o a)
-> Automaton a i o a -> Automaton a i o a
forall a b. (a -> b) -> a -> b
$ a -> Automaton a i o a -> Automaton a i o a
forall p i o a. p -> Automaton p i o a -> Automaton p i o a
Count a
p Automaton a i o a
r')
  go Automaton a i o a
a = ([], Automaton a i o a
a)

-- | Run a Phaser object on input values produced by a monadic action
-- and passing the output values to another monadic function. The input action
-- should return 'Nothing' when there is no more input. If there is more than
-- one final result: the left one is chosen, and all the outputs leading to it
-- are also output.
stream :: (Monoid p, PhaserType s, Monad m) =>
  p -> s p i o a -> m (Maybe [i]) -> ([o] -> m ()) ->
  m (Either [(p,[String])] a)
stream :: forall p (s :: * -> * -> * -> * -> *) (m :: * -> *) i o a.
(Monoid p, PhaserType s, Monad m) =>
p
-> s p i o a
-> m (Maybe [i])
-> ([o] -> m ())
-> m (Either [(p, [String])] a)
stream p
p0 s p i o a
a1 m (Maybe [i])
r [o] -> m ()
w = Automaton p i o a -> m (Either [(p, [String])] a)
forall {a}. Automaton p i o a -> m (Either [(p, [String])] a)
go (s p i o a -> Automaton p i o a
forall p i o a. Monoid p => s p i o a -> Automaton p i o a
forall (s :: * -> * -> * -> * -> *) p i o a.
(PhaserType s, Monoid p) =>
s p i o a -> Automaton p i o a
toAutomaton s p i o a
a1) where
  go :: Automaton p i o a -> m (Either [(p, [String])] a)
go Automaton p i o a
a = do
    let ([o]
o,Automaton p i o a
a1) = Automaton p i o a -> ([o], Automaton p i o a)
forall p i o a.
Monoid p =>
Automaton p i o a -> ([o], Automaton p i o a)
outputs Automaton p i o a
a
    case [o]
o of
      [] -> () -> m ()
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
      [o]
_ -> [o] -> m ()
w [o]
o
    Maybe [i]
i <- m (Maybe [i])
r
    case Maybe [i]
i of
      Maybe [i]
Nothing -> Automaton p i o a -> m (Either [(p, [String])] a)
forall {i} {b}. Automaton p i o b -> m (Either [(p, [String])] b)
fin1 Automaton p i o a
a1
      Just [i]
i' -> Automaton p i o a -> m (Either [(p, [String])] a)
go (Automaton p i o a -> m (Either [(p, [String])] a))
-> Automaton p i o a -> m (Either [(p, [String])] a)
forall a b. (a -> b) -> a -> b
$ Automaton p i o a -> [i] -> Automaton p i o a
forall p i o a.
Monoid p =>
Automaton p i o a -> [i] -> Automaton p i o a
run Automaton p i o a
a1 [i]
i'
  fin1 :: Automaton p i o b -> m (Either [(p, [String])] b)
fin1 = Automaton p i o b -> m (Either [(p, [String])] b)
forall {i} {b}. Automaton p i o b -> m (Either [(p, [String])] b)
fin2 (Automaton p i o b -> m (Either [(p, [String])] b))
-> (Automaton p i o b -> Automaton p i o b)
-> Automaton p i o b
-> m (Either [(p, [String])] b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Automaton p i o b, Bool) -> Automaton p i o b
forall a b. (a, b) -> a
fst ((Automaton p i o b, Bool) -> Automaton p i o b)
-> (Automaton p i o b -> (Automaton p i o b, Bool))
-> Automaton p i o b
-> Automaton p i o b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. p -> Automaton p i o b -> (Automaton p i o b, Bool)
forall {p} {i} {o} {a}.
Monoid p =>
p -> Automaton p i o a -> (Automaton p i o a, Bool)
clean p
forall a. Monoid a => a
mempty
  clean :: p -> Automaton p i o a -> (Automaton p i o a, Bool)
clean p
_ r :: Automaton p i o a
r@(Result a
_) = (Automaton p i o a
r,Bool
True)
  clean p
p0 (Count p
p Automaton p i o a
r) = let
    p' :: p
p' = p -> p -> p
forall a. Monoid a => a -> a -> a
mappend p
p0 p
p
    (Automaton p i o a
r',Bool
c) = p -> Automaton p i o a -> (Automaton p i o a, Bool)
clean p
p' Automaton p i o a
r
    in (p -> Automaton p i o a -> Automaton p i o a
forall p i o a. p -> Automaton p i o a -> Automaton p i o a
Count p
p Automaton p i o a
r', Bool
c)
  clean p
p (Yield o
o Automaton p i o a
r) = let
    (Automaton p i o a
r',Bool
c) = p -> Automaton p i o a -> (Automaton p i o a, Bool)
clean p
p Automaton p i o a
r
    in (o -> Automaton p i o a -> Automaton p i o a
forall p i o a. o -> Automaton p i o a -> Automaton p i o a
Yield o
o Automaton p i o a
r', Bool
c)
  clean p
p (Automaton p i o a
a :+++ Automaton p i o a
b) = case (p -> Automaton p i o a -> (Automaton p i o a, Bool)
clean p
p Automaton p i o a
a, p -> Automaton p i o a -> (Automaton p i o a, Bool)
clean p
p Automaton p i o a
b) of
    (a' :: (Automaton p i o a, Bool)
a'@(Automaton p i o a
_,Bool
True),(Automaton p i o a, Bool)
_) -> (Automaton p i o a, Bool)
a'
    ((Automaton p i o a, Bool)
_,b' :: (Automaton p i o a, Bool)
b'@(Automaton p i o a
_,Bool
True)) -> (Automaton p i o a, Bool)
b'
    ((Automaton p i o a
a',Bool
False),(Automaton p i o a
b',Bool
False)) -> (Automaton p i o a -> Automaton p i o a
forall {a} {i} {o} {a}.
Monoid a =>
Automaton a i o a -> Automaton a i o a
prune1 (Automaton p i o a
a' Automaton p i o a -> Automaton p i o a -> Automaton p i o a
forall p i o a.
Automaton p i o a -> Automaton p i o a -> Automaton p i o a
:+++ Automaton p i o a
b'), Bool
False)
  clean p
p (GetCount p -> Automaton p i o a
n) = p -> Automaton p i o a -> (Automaton p i o a, Bool)
clean p
p (p -> Automaton p i o a
n p
p)
  clean p
_ Automaton p i o a
a = (Automaton p i o a
a,Bool
False)
  fin2 :: Automaton p i o b -> m (Either [(p, [String])] b)
fin2 Automaton p i o b
a = do
    let ([o]
o,Automaton p i o b
a1) = Automaton p i o b -> ([o], Automaton p i o b)
forall p i o a.
Monoid p =>
Automaton p i o a -> ([o], Automaton p i o a)
outputs Automaton p i o b
a
    [o] -> m ()
w [o]
o
    Either [(p, [String])] b -> m (Either [(p, [String])] b)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either [(p, [String])] b -> m (Either [(p, [String])] b))
-> Either [(p, [String])] b -> m (Either [(p, [String])] b)
forall a b. (a -> b) -> a -> b
$ case p -> Automaton p i o b -> Either [(p, [String])] [b]
forall p i o a.
Monoid p =>
p -> Automaton p i o a -> Either [(p, [String])] [a]
extract p
p0 Automaton p i o b
a1 of
      Right (b
r:[b]
_) -> b -> Either [(p, [String])] b
forall a b. b -> Either a b
Right b
r
      Left [(p, [String])]
e -> [(p, [String])] -> Either [(p, [String])] b
forall a b. a -> Either a b
Left [(p, [String])]
e
      Either [(p, [String])] [b]
_ -> [(p, [String])] -> Either [(p, [String])] b
forall a b. a -> Either a b
Left [] -- I believe this case to be unreachable, but ghc unsure.