
On Thu, 21 Feb 2002, Mark Wotton wrote:
Hi,
I'm trying out some combinatorial parsers, and I ran into a slightly inelegant construction. To parse a sequence of things, we have a function like
pThen3 :: (a->b->c->d) -> Parser a -> Parser b -> Parser c -> Parser d pThen3 combine p1 p2 p3 toks = [(combine v1 v2 v3, toks3) | (v1, toks1) <- p1 toks, (v2, toks2) <- p2 toks1, (v3, toks3) <- p3 toks2]
The problem with this is that this structure has to be duplicated for pThen2, pThen4, and so on. These other forms are very similar to pThen3, but there seems to be no way to capture this in Haskell's type system, as the combine function has a different signature for each pThenX. (This is actually the first time the Haskell type system has got in my way rather than helping.) Is there a way around this problem?
Yes there is a way around this problem. You can use multi parameter type classes to create (and give a type to) a function such as pThenX. The details are worked out in the paper "Faking it" by Conor McBride. In that paper shows how to implement a generic zipWith in Haskell. The same technique should work for your function. The paper can be found on: http://www.dur.ac.uk/~dcs1ctm/ Cheers, /Josef