slightly too(?) complex list pattern matching

Hal Daume III hdaume@ISI.EDU
Mon, 17 Jun 2002 13:13:50 -0700 (PDT)


Hi all,

I don't think I can do this, but I figured I'd ask anyway.  Suppose I
have:

> data X = X | Y | Z

and I want to match against a list of Xs.  But all I want is to ensure
that there's a Y followed by a Z, but I don't care if there's anything
else (or lots of other stuff) in between.  Namely, I want to match:

  .*Y.*Z.*

Now, I can match YZ.* easily with:

> foo (X:Y:_) = ...

furthermore, my matches never require any backtracking, so you won't see
something like ".*X.*Y.*X.*Z" which could possibly make you backtrack (so,
there are no duplicates in what I'm matching against).

Anway, the current way I do this is by having a function:

> match [] _ = True
> match (m:ms) (x:xs)
>     | m == x    = match ms xs
>     | otherwise = match (m:ms) xs

(Actually, I do a bit more -- I return Maybe [Int] where Nothing signifies
that the match failed and Just intList specifies the indices of the
matched elements, but this is superfluous).

so this requires me to write things like:

> foo l
>     | Just indices <- [X,Y] `match` l = 
>       let [x,y] = map (l!!) indices
>       in  ...

instead of the nice haskellesque syntax:

> foo [..,x@X,..,y@Y,..] = ...

anyway, I'm curious if anyone else has pounded against this wall at all
and if there's any tool (drift, or something perhaps) that would allow me
to write more succinct versions?

Thanks!

 - Hal

--
Hal Daume III

 "Computer science is no more about computers    | hdaume@isi.edu
  than astronomy is about telescopes." -Dijkstra | www.isi.edu/~hdaume