caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Pattern matching over lazy lists
@ 2007-07-10 22:38 Jon Harrop
  2007-07-11  8:44 ` [Caml-list] " Loup Vaillant
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Jon Harrop @ 2007-07-10 22:38 UTC (permalink / raw)
  To: caml-list


What's the best way to do this?

I was thinking of forcing the first few elements of a lazy list before pattern 
matching and then looking for forced values in the lists as patterns but I 
don't think you can deconstruct a lazy value in a pattern match...

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
The OCaml Journal
http://www.ffconsultancy.com/products/ocaml_journal/?e


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Caml-list] Pattern matching over lazy lists
  2007-07-10 22:38 Pattern matching over lazy lists Jon Harrop
@ 2007-07-11  8:44 ` Loup Vaillant
  2007-07-11 11:13 ` Markus E.L.
  2007-07-11 15:51 ` Martin Jambon
  2 siblings, 0 replies; 4+ messages in thread
From: Loup Vaillant @ 2007-07-11  8:44 UTC (permalink / raw)
  To: caml-list

(Sorry for the double post)

2007/7/11, Jon Harrop <jon@ffconsultancy.com>:
> What's the best way to do this?
>
> I was thinking of forcing the first few elements of a lazy list before pattern
> matching and then looking for forced values in the lists as patterns but I
> don't think you can deconstruct a lazy value in a pattern match...


You are talking about streams, right? Not just the suspension of a
regular list? Camlp4 provide "functional streams", which are not
destructive. If you don't want to use that...

...At least, you can deconstruct the very first suspension :

match force l with
| Empty -> (****)
| Cons x l -> (****)

might do it. maybe :

match hd (force l) with
| 0 -> (****)
| x -> (****)

would be better for your purpose.

However, with more than one element (3 here) :

match
 hd (force l),
 hd (force (tl (force l))),
 hd (force (tl (force (tl (force l)))))
with
| 0, 0, 0 -> (****)
| x, y, z -> (****)

Quite ugly. In that case, I suggest you write a "peek_n" function
which take a stream as input, and provide you a list (or tuple, or
whatever) as output, so you can match it directly :

match peek_n 3 l with
| [0; 0; 0] -> (****)
| [x; y; z] -> (****)
| _ -> failwith "impossible error"

Did I answer your question?

Loup Vaillant

PS :

> I don't think you can deconstruct a lazy value in a pattern match...

Why not? A lazy value is a value like any other. (Whoops, I just
looked at the Lazy module, which hide some magic... compiler
optimizations?)


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Caml-list] Pattern matching over lazy lists
  2007-07-10 22:38 Pattern matching over lazy lists Jon Harrop
  2007-07-11  8:44 ` [Caml-list] " Loup Vaillant
@ 2007-07-11 11:13 ` Markus E.L.
  2007-07-11 15:51 ` Martin Jambon
  2 siblings, 0 replies; 4+ messages in thread
From: Markus E.L. @ 2007-07-11 11:13 UTC (permalink / raw)
  To: caml-list


> What's the best way to do this?
>
> I was thinking of forcing the first few elements of a lazy list before pattern 
> matching and then looking for forced values in the lists as patterns but I 
> don't think you can deconstruct a lazy value in a pattern match...


I'll put in my 2 cents here, since I've been working on something like
this. 

Yes, I think you're right: A lazy list when forced, gives a list (so
the complete list is produced). On the other side a List of lazy
elements still is a complete list -- among other things the number of
elements is fixed when the list is computed. Both situations are
unsuitable for things like parsers, which I assume is the thing you're
aiming at.

As far as I understand it, streams and stream parsers are not
completely functional, so not suitable for arbitrary back tracking
(which I sometimes would like to do). If I had a lazy list, I could write

  match lazy_list with

    Plus  :: tail ->   (parse_term_list n tail)
    Minus :: tail -> - (parse_term_list (-n) tail)
    _ ::          -> raise (Parse_Error "expected + or - here")
    []            -> n

Unfortunately there are no lazy lists in this sense. The solution I'm
presently aiming at, works like this instead:

  match (prefix 5 token_stream) with

    ....

  
where (prefix k) gives you a list of at least k tokens from the stream
(if available) or less (if not available).

'token_stream' and 'prefix' can be implemented a way that is more
efficient than just creating the prefix list every time, but there
still is a certain amount of overhead, because, at the end, there
always is a point where the algorithm needs to append at the list.

Not the high art of programming, I know, but I didn't find any other
non-camlp4 solution that allows me to read the grammar clearly from
source.

Regards -- Markus



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Caml-list] Pattern matching over lazy lists
  2007-07-10 22:38 Pattern matching over lazy lists Jon Harrop
  2007-07-11  8:44 ` [Caml-list] " Loup Vaillant
  2007-07-11 11:13 ` Markus E.L.
@ 2007-07-11 15:51 ` Martin Jambon
  2 siblings, 0 replies; 4+ messages in thread
From: Martin Jambon @ 2007-07-11 15:51 UTC (permalink / raw)
  To: Jon Harrop; +Cc: caml-list

On Tue, 10 Jul 2007, Jon Harrop wrote:

>
> What's the best way to do this?
>
> I was thinking of forcing the first few elements of a lazy list before pattern
> matching and then looking for forced values in the lists as patterns but I
> don't think you can deconstruct a lazy value in a pattern match...

You can use this approach:

   http://martin.jambon.free.fr/micmatch-manual.html#htoc13

I found this convenient for "sliding window" signal analysis.

It requires micmatch and a 3.09-compatible version of camlp4.


Martin


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2007-07-11 15:51 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-07-10 22:38 Pattern matching over lazy lists Jon Harrop
2007-07-11  8:44 ` [Caml-list] " Loup Vaillant
2007-07-11 11:13 ` Markus E.L.
2007-07-11 15:51 ` Martin Jambon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).