push :: a -> (a -> Bool) -> (a -> Mismatch) -> Grammar p t (a :- t)
push a p e = PartialIso f g
  where
    f t = a :- t
    g (a' :- t)
      | p a' = Right t
      | otherwise = Left $ e a'


-- | 2-tuple grammar. Construct on forward run, deconstruct on
-- backward run.
push :: a -> (a -> Bool) -> (a -> Mismatch) -> Grammar p t (a :- t)
push a p e = PartialIso f g
  where
    f t = a :- t
    g (a' :- t)
      | p a' = Right t
      | otherwise = Left $ e a'


-- | 2-tuple grammar. Construct on forward run, deconstruct on
-- backward run.
push a p e = PartialIso f g
  where
    f t = a :- t
    g (a' :- t)
      | p a' = Right t
      | otherwise = Left $ e a'


-- | 2-tuple grammar. Construct on forward run, deconstruct on
-- backward run.