race :: Parser a -> Parser a -> Parser a 
race (Parser m) (Parser n) = Parser $ \s -> case m s of
  Pure a e -> case n s of -- old state
    Pure a' e' -> Pure a (e <> e')
    Fail e'    -> Pure a (e <> e')
    r -> r
  Fail e -> case n s of -- old state
    Pure a' e' -> Pure a' e'
    Fail e'    -> Fail (e <> e')
    r -> r
  l@(Commit a t xs) -> case n s of -- old state
    r@(Commit a' t' xs') -> case _parserLocation t `compare` _parserLocation t' of
      LT -> r
      EQ -> Commit a t (xs <> xs')
      GT -> l
    Err el e
      | el == _parserLocation t -> Commit a t (xs <> e^.expected)
      -- fall through
    _ -> l
  l@(Err el e) -> case n s of -- old state
    r@(Err el' e') -> case compare el el' of
      LT -> r
      EQ -> Err el (mappend e e')
      GT -> l
    r@(Commit a t xs)
      | el == _parserLocation t -> Commit a t (e^.expected <> xs)
      -- fall through
    r -> r
race :: Parser a -> Parser a -> Parser a
race (Parser m) (Parser n) = Parser $ \s -> case m s of
  Pure a e -> case n s of -- old state
    Pure a' e' -> Pure a (e <> e')
    Fail e'    -> Pure a (e <> e')
    r -> r
  Fail e -> case n s of -- old state
    Pure a' e' -> Pure a' e'
    Fail e'    -> Fail (e <> e')
    r -> r
  l@(Commit a t xs) -> case n s of -- old state
    r@(Commit a' t' xs') -> case _parserLocation t `compare` _parserLocation t' of
      LT -> r
      EQ -> Commit a t (xs <> xs')
      GT -> l
    Err el e
      | el == _parserLocation t -> Commit a t (xs <> e^.expected)
      -- fall through
    _ -> l
  l@(Err el e) -> case n s of -- old state
    r@(Err el' e') -> case compare el el' of
      LT -> r
      EQ -> Err el (mappend e e')
      GT -> l
    r@(Commit a t xs)
      | el == _parserLocation t -> Commit a t (e^.expected <> xs)
      -- fall through
    r -> r
race (Parser m) (Parser n) = Parser $ \s -> case m s of
  Pure a e -> case n s of -- old state
    Pure a' e' -> Pure a (e <> e')
    Fail e'    -> Pure a (e <> e')
    r -> r
  Fail e -> case n s of -- old state
    Pure a' e' -> Pure a' e'
    Fail e'    -> Fail (e <> e')
    r -> r
  l@(Commit a t xs) -> case n s of -- old state
    r@(Commit a' t' xs') -> case _parserLocation t `compare` _parserLocation t' of
      LT -> r
      EQ -> Commit a t (xs <> xs')
      GT -> l
    Err el e
      | el == _parserLocation t -> Commit a t (xs <> e^.expected)
      -- fall through
    _ -> l
  l@(Err el e) -> case n s of -- old state
    r@(Err el' e') -> case compare el el' of
      LT -> r
      EQ -> Err el (mappend e e')
      GT -> l
    r@(Commit a t xs)
      | el == _parserLocation t -> Commit a t (e^.expected <> xs)
      -- fall through
    r -> r