Haskell problem

Josef Svenningsson josefs@cs.chalmers.se
Thu, 21 Feb 2002 15:50:19 +0100 (MET)

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: