I recently started learning Haskell and I am currently working through the "Higher Order Functions for Parsing" paper. You can find it Here.
The paper defines a function called many
.
many :: parser * ** -> parser * [**] many p = ((p $then many p) $using cons) $alt (succeed [])
I am trying to convert it to Haskell.
succeed v inp = [(v, inp)]
fail' inp = []
satisfy p [] = fail' []
satisfy p (x:xs)
| p x = succeed x xs
| otherwise = fail' xs
literal x = satisfy (==x)
alt' p1 p2 = \inp -> p1 inp ++ p2 inp
then' p1 p2 = \inp -> [((v1, v2), out2) | (v1, out1) <- p1 inp, (v2, out2) <- p2 out1]
using' p f = \inp -> [(f v, out) | (v, out) <- p inp]
many' p = ((p `then'` (many' p)) `using'` (:)) `alt'` (succeed [])
I have tested all the pieces in isolation and they work fine. But the definition of many is giving me error. I can't seem to figure out what is the issue. I am doing exactly how it's mentioned in the paper.
Main.hs:19:56: error: • Couldn't match type ‘[a0]’ with ‘[(a, b)] -> [(a, b)]’ Expected type: t -> [([(a, b)] -> [(a, b)], t)] Actual type: t -> [([a0], t)] • In the second argument of ‘alt'’, namely ‘(succeed [])’ In the expression: ((p `then'` (many' p)) `using'` (:)) `alt'` (succeed []) In an equation for ‘many'’: many' p = ((p `then'` (many' p)) `using'` (:)) `alt'` (succeed []) • Relevant bindings include p :: t -> [(a, t)] (bound at Stum.hs:19:7) many' :: (t -> [(a, t)]) -> t -> [(b, t)] (bound at Stum.hs:19:1) | 19 | many' p = ((p `then'` (many' p)) `using'` (:)) `alt'` (succeed []) | Failed, no modules loaded. Prelude>