caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] pattern matching on strings
@ 2011-09-14 20:16 Walter Cazzola
  2011-09-14 20:40 ` Basile Starynkevitch
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Walter Cazzola @ 2011-09-14 20:16 UTC (permalink / raw)
  To: OCaML Mailing List

[-- Attachment #1: Type: TEXT/PLAIN, Size: 665 bytes --]

Hi all,
I'm just trying to write a recursive function that iterates¹ on a string
and I'd like to use pattern matching as in:

let rec iter f s =
   match s with
      | ""  -> unit;
      | c^s1 -> f c; iter f s1;;

but the ^ concatenates 2 strings and not a char with a string and above
all seems to be inadmissible in the patterns.

Does this mean that I can't write a function on strings by pattern
matching or is there something I don't know?²

Thanks for the help
Walter

¹ I know that exists String.iter but I'd like to improve my skill in
   writing functions by using pattern matching
² I read about micmatch but I'd like to avoid non standard packages.
-- 

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

* Re: [Caml-list] pattern matching on strings
  2011-09-14 20:16 [Caml-list] pattern matching on strings Walter Cazzola
@ 2011-09-14 20:40 ` Basile Starynkevitch
  2011-09-16 21:20   ` Richard W.M. Jones
  2011-09-14 20:57 ` Philippe Veber
  2011-09-14 21:14 ` Philippe Strauss
  2 siblings, 1 reply; 8+ messages in thread
From: Basile Starynkevitch @ 2011-09-14 20:40 UTC (permalink / raw)
  To: Walter Cazzola; +Cc: OCaML Mailing List

On Wed, 14 Sep 2011 22:16:42 +0200 (CEST)
Walter Cazzola <cazzola@dico.unimi.it> wrote:
> 
> Does this mean that I can't write a function on strings by pattern
> matching or is there something I don't know?

No, standard Ocaml 3.12 has no way of doing matching (in the sense of the match
expression) on [the content of] Ocaml strings. (Of course, some library functions give you
regexprs, scanf, ... etc, and you could match on constant Ocaml strings...).

AFAIK, current Ocaml has no abstract matching, like the "views" in Wadler's sense (e.g.
his POPL87 paper).

Even in domain specific languages, abstract pattern matching is not easy to implement
(shameless plug for my DSL11 http://eptcs.org/content.cgi?DSL2011 paper, see gcc-melt.org
or http://arxiv.org/abs/1109.0779v1 ...)

And there is a reason why you cannot match (in Ocaml) on the content of strings (or
arrays). It won't be easy to implement efficiently (you would need to copy a substring or
subarray when matching)

Cheers.
-- 
Basile STARYNKEVITCH         http://starynkevitch.net/Basile/
email: basile<at>starynkevitch<dot>net mobile: +33 6 8501 2359
8, rue de la Faiencerie, 92340 Bourg La Reine, France
*** opinions {are only mine, sont seulement les miennes} ***

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

* Re: [Caml-list] pattern matching on strings
  2011-09-14 20:16 [Caml-list] pattern matching on strings Walter Cazzola
  2011-09-14 20:40 ` Basile Starynkevitch
@ 2011-09-14 20:57 ` Philippe Veber
  2011-09-14 21:44   ` Raphael Proust
  2011-09-14 21:14 ` Philippe Strauss
  2 siblings, 1 reply; 8+ messages in thread
From: Philippe Veber @ 2011-09-14 20:57 UTC (permalink / raw)
  To: Walter Cazzola; +Cc: OCaML Mailing List

[-- Attachment #1: Type: text/plain, Size: 2463 bytes --]

Hi Walter,

Contrary to Prolog or Haskell, strings in ocaml are not represented as char
lists. They are exactly like char array, but have their own type, operations
and syntax : strings are created with String.make (similar to Array.make),
their length is given by String.length (sim. to Array.length) and the chars
are accessed with the notation s.[i] (similar to t.(i)). Actually I don't
know why they are not defined like char arrays (anyone on this ?). Long
story short, recursive formulations on strings (likewise for array) will
often rely on indices (and thus, not much on pattern matching). Note that
you can use optional arguments to hide indices :

let rec iter f ?(k = 0) s =
  if k < String.length s then (
    f s.[k] ;
    iter f ~k:(k + 1) s
  )

let _ = iter print_char "abc";;


The closest to your request I see can be achieved using ocaml batteries (*),
by transforming your string into a list:

let rec iter_aux f = function
    [] -> ()
  | c :: s1 -> f c ; iter_aux f s1
let iter f s = iter_aux f (String.explode s)

But this won't be very efficient !

You won't find advanced string pattern matching in core ocaml. But micmatch
seems a nice way to go if that's what you're looking for.

cheers,
Philippe.

(*) http://batteries.forge.ocamlcore.org/


2011/9/14 Walter Cazzola <cazzola@dico.unimi.it>

> Hi all,
> I'm just trying to write a recursive function that iterates¹ on a string
> and I'd like to use pattern matching as in:
>
> let rec iter f s =
>  match s with
>     | ""  -> unit;
>     | c^s1 -> f c; iter f s1;;
>
> but the ^ concatenates 2 strings and not a char with a string and above
> all seems to be inadmissible in the patterns.
>
> Does this mean that I can't write a function on strings by pattern
> matching or is there something I don't know?²
>
> Thanks for the help
> Walter
>
> ¹ I know that exists String.iter but I'd like to improve my skill in
>  writing functions by using pattern matching
> ² I read about micmatch but I'd like to avoid non standard packages.
> --
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa-roc.inria.fr/**wws/info/caml-list<https://sympa-roc.inria.fr/wws/info/caml-list>
> Beginner's list: http://groups.yahoo.com/group/**ocaml_beginners<http://groups.yahoo.com/group/ocaml_beginners>
> Bug reports: http://caml.inria.fr/bin/caml-**bugs<http://caml.inria.fr/bin/caml-bugs>
>
>

[-- Attachment #2: Type: text/html, Size: 4323 bytes --]

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

* Re: [Caml-list] pattern matching on strings
  2011-09-14 20:16 [Caml-list] pattern matching on strings Walter Cazzola
  2011-09-14 20:40 ` Basile Starynkevitch
  2011-09-14 20:57 ` Philippe Veber
@ 2011-09-14 21:14 ` Philippe Strauss
  2 siblings, 0 replies; 8+ messages in thread
From: Philippe Strauss @ 2011-09-14 21:14 UTC (permalink / raw)
  To: caml-list

It reminds me of the micmatch/mikmatch project(s), http://martin.jambon.free.fr/micmatch.html, but never used it, only remember reading the announce on the hump or this list.

Le 14 sept. 2011 à 22:16, Walter Cazzola a écrit :

> Hi all,
> I'm just trying to write a recursive function that iterates¹ on a string
> and I'd like to use pattern matching as in:
> 
> let rec iter f s =
>  match s with
>     | ""  -> unit;
>     | c^s1 -> f c; iter f s1;;
> 
> but the ^ concatenates 2 strings and not a char with a string and above
> all seems to be inadmissible in the patterns.
> 
> Does this mean that I can't write a function on strings by pattern
> matching or is there something I don't know?²
> 
> Thanks for the help
> Walter
> 
> ¹ I know that exists String.iter but I'd like to improve my skill in
>  writing functions by using pattern matching
> ² I read about micmatch but I'd like to avoid non standard packages.
> -- 
> -- 
> Caml-list mailing list.  Subscription management and archives:
> https://sympa-roc.inria.fr/wws/info/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
> 



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

* Re: [Caml-list] pattern matching on strings
  2011-09-14 20:57 ` Philippe Veber
@ 2011-09-14 21:44   ` Raphael Proust
  2011-09-16 22:18     ` Philippe Veber
  0 siblings, 1 reply; 8+ messages in thread
From: Raphael Proust @ 2011-09-14 21:44 UTC (permalink / raw)
  To: Philippe Veber; +Cc: Walter Cazzola, OCaML Mailing List

Richard Jones described the internals of OCaml quite concisely. The
difference between char arrays and strings is exposed in part two of
his series of posts:
https://rwmj.wordpress.com/2009/08/05/ocaml-internals-part-2-strings-and-other-types/

There is a pointer to
http://caml.inria.fr/pub/ml-archives/caml-list/2002/08/e109df224ff0150b302033e2002dbf87.en.html
in the article.

On 9/14/11, Philippe Veber <philippe.veber@gmail.com> wrote:
> Hi Walter,
>
> Contrary to Prolog or Haskell, strings in ocaml are not represented as char
> lists. They are exactly like char array, but have their own type, operations
> and syntax : strings are created with String.make (similar to Array.make),
> their length is given by String.length (sim. to Array.length) and the chars
> are accessed with the notation s.[i] (similar to t.(i)). Actually I don't
> know why they are not defined like char arrays (anyone on this ?). Long
> story short, recursive formulations on strings (likewise for array) will
> often rely on indices (and thus, not much on pattern matching). Note that
> you can use optional arguments to hide indices :
>
> let rec iter f ?(k = 0) s =
>   if k < String.length s then (
>     f s.[k] ;
>     iter f ~k:(k + 1) s
>   )
>
> let _ = iter print_char "abc";;
>
>
> The closest to your request I see can be achieved using ocaml batteries (*),
> by transforming your string into a list:
>
> let rec iter_aux f = function
>     [] -> ()
>   | c :: s1 -> f c ; iter_aux f s1
> let iter f s = iter_aux f (String.explode s)
>
> But this won't be very efficient !
>
> You won't find advanced string pattern matching in core ocaml. But micmatch
> seems a nice way to go if that's what you're looking for.
>
> cheers,
> Philippe.
>
> (*) http://batteries.forge.ocamlcore.org/
>
>
> 2011/9/14 Walter Cazzola <cazzola@dico.unimi.it>
>
>> Hi all,
>> I'm just trying to write a recursive function that iterates¹ on a string
>> and I'd like to use pattern matching as in:
>>
>> let rec iter f s =
>>  match s with
>>     | ""  -> unit;
>>     | c^s1 -> f c; iter f s1;;
>>
>> but the ^ concatenates 2 strings and not a char with a string and above
>> all seems to be inadmissible in the patterns.
>>
>> Does this mean that I can't write a function on strings by pattern
>> matching or is there something I don't know?²
>>
>> Thanks for the help
>> Walter
>>
>> ¹ I know that exists String.iter but I'd like to improve my skill in
>>  writing functions by using pattern matching
>> ² I read about micmatch but I'd like to avoid non standard packages.
>> --
>> --
>> Caml-list mailing list.  Subscription management and archives:
>> https://sympa-roc.inria.fr/**wws/info/caml-list<https://sympa-roc.inria.fr/wws/info/caml-list>
>> Beginner's list:
>> http://groups.yahoo.com/group/**ocaml_beginners<http://groups.yahoo.com/group/ocaml_beginners>
>> Bug reports:
>> http://caml.inria.fr/bin/caml-**bugs<http://caml.inria.fr/bin/caml-bugs>
>>
>>
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa-roc.inria.fr/wws/info/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>
>


-- 
_______
Raphael


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

* Re: [Caml-list] pattern matching on strings
  2011-09-14 20:40 ` Basile Starynkevitch
@ 2011-09-16 21:20   ` Richard W.M. Jones
  2011-09-17  8:15     ` Basile Starynkevitch
  0 siblings, 1 reply; 8+ messages in thread
From: Richard W.M. Jones @ 2011-09-16 21:20 UTC (permalink / raw)
  To: Basile Starynkevitch; +Cc: Walter Cazzola, OCaML Mailing List

On Wed, Sep 14, 2011 at 10:40:11PM +0200, Basile Starynkevitch wrote:
> And there is a reason why you cannot match (in Ocaml) on the content
> of strings (or arrays). It won't be easy to implement efficiently
> (you would need to copy a substring or subarray when matching)

How about just prefix matching?  That on its own would be very useful.

For example in web app that was passed arguments foo_1, foo_2, bar_1,
bar_5 you could parse the arguments like this:

  match arg with
  | "foo_" ^ s -> (* ... *)
  | "bar_" ^ s -> (* ... *)

Rich.

-- 
Richard Jones
Red Hat

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

* Re: [Caml-list] pattern matching on strings
  2011-09-14 21:44   ` Raphael Proust
@ 2011-09-16 22:18     ` Philippe Veber
  0 siblings, 0 replies; 8+ messages in thread
From: Philippe Veber @ 2011-09-16 22:18 UTC (permalink / raw)
  To: Raphael Proust; +Cc: Walter Cazzola, OCaML Mailing List

[-- Attachment #1: Type: text/plain, Size: 3685 bytes --]

Thank you Raphael !
Indeed, keeping the C encoding underneath strings (and arrays) is a nice
property.
ph.

2011/9/14 Raphael Proust <raphlalou@gmail.com>

> Richard Jones described the internals of OCaml quite concisely. The
> difference between char arrays and strings is exposed in part two of
> his series of posts:
>
> https://rwmj.wordpress.com/2009/08/05/ocaml-internals-part-2-strings-and-other-types/
>
> There is a pointer to
>
> http://caml.inria.fr/pub/ml-archives/caml-list/2002/08/e109df224ff0150b302033e2002dbf87.en.html
> in the article.
>
> On 9/14/11, Philippe Veber <philippe.veber@gmail.com> wrote:
> > Hi Walter,
> >
> > Contrary to Prolog or Haskell, strings in ocaml are not represented as
> char
> > lists. They are exactly like char array, but have their own type,
> operations
> > and syntax : strings are created with String.make (similar to
> Array.make),
> > their length is given by String.length (sim. to Array.length) and the
> chars
> > are accessed with the notation s.[i] (similar to t.(i)). Actually I don't
> > know why they are not defined like char arrays (anyone on this ?). Long
> > story short, recursive formulations on strings (likewise for array) will
> > often rely on indices (and thus, not much on pattern matching). Note that
> > you can use optional arguments to hide indices :
> >
> > let rec iter f ?(k = 0) s =
> >   if k < String.length s then (
> >     f s.[k] ;
> >     iter f ~k:(k + 1) s
> >   )
> >
> > let _ = iter print_char "abc";;
> >
> >
> > The closest to your request I see can be achieved using ocaml batteries
> (*),
> > by transforming your string into a list:
> >
> > let rec iter_aux f = function
> >     [] -> ()
> >   | c :: s1 -> f c ; iter_aux f s1
> > let iter f s = iter_aux f (String.explode s)
> >
> > But this won't be very efficient !
> >
> > You won't find advanced string pattern matching in core ocaml. But
> micmatch
> > seems a nice way to go if that's what you're looking for.
> >
> > cheers,
> > Philippe.
> >
> > (*) http://batteries.forge.ocamlcore.org/
> >
> >
> > 2011/9/14 Walter Cazzola <cazzola@dico.unimi.it>
> >
> >> Hi all,
> >> I'm just trying to write a recursive function that iterates¹ on a string
> >> and I'd like to use pattern matching as in:
> >>
> >> let rec iter f s =
> >>  match s with
> >>     | ""  -> unit;
> >>     | c^s1 -> f c; iter f s1;;
> >>
> >> but the ^ concatenates 2 strings and not a char with a string and above
> >> all seems to be inadmissible in the patterns.
> >>
> >> Does this mean that I can't write a function on strings by pattern
> >> matching or is there something I don't know?²
> >>
> >> Thanks for the help
> >> Walter
> >>
> >> ¹ I know that exists String.iter but I'd like to improve my skill in
> >>  writing functions by using pattern matching
> >> ² I read about micmatch but I'd like to avoid non standard packages.
> >> --
> >> --
> >> Caml-list mailing list.  Subscription management and archives:
> >> https://sympa-roc.inria.fr/**wws/info/caml-list<
> https://sympa-roc.inria.fr/wws/info/caml-list>
> >> Beginner's list:
> >> http://groups.yahoo.com/group/**ocaml_beginners<
> http://groups.yahoo.com/group/ocaml_beginners>
> >> Bug reports:
> >> http://caml.inria.fr/bin/caml-**bugs<http://caml.inria.fr/bin/caml-bugs
> >
> >>
> >>
> >
> > --
> > Caml-list mailing list.  Subscription management and archives:
> > https://sympa-roc.inria.fr/wws/info/caml-list
> > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> > Bug reports: http://caml.inria.fr/bin/caml-bugs
> >
> >
>
>
> --
> _______
> Raphael
>

[-- Attachment #2: Type: text/html, Size: 5744 bytes --]

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

* Re: [Caml-list] pattern matching on strings
  2011-09-16 21:20   ` Richard W.M. Jones
@ 2011-09-17  8:15     ` Basile Starynkevitch
  0 siblings, 0 replies; 8+ messages in thread
From: Basile Starynkevitch @ 2011-09-17  8:15 UTC (permalink / raw)
  To: Richard W.M. Jones; +Cc: Walter Cazzola, OCaML Mailing List

On Fri, 16 Sep 2011 22:20:05 +0100
"Richard W.M. Jones" <rich@annexia.org> wrote:

> On Wed, Sep 14, 2011 at 10:40:11PM +0200, Basile Starynkevitch wrote:
> > And there is a reason why you cannot match (in Ocaml) on the content
> > of strings (or arrays). It won't be easy to implement efficiently
> > (you would need to copy a substring or subarray when matching)
> 
> How about just prefix matching?  That on its own would be very useful.
> 
> For example in web app that was passed arguments foo_1, foo_2, bar_1,
> bar_5 you could parse the arguments like this:
> 
>   match arg with
>   | "foo_" ^ s -> (* ..code_foo.. *)
>   | "bar_" ^ s -> (* ..code_bar.. *)

[[NB I edited Richard's examples' comments]]

If the pattern variable s is indeed used in code_foo or code_bar you need to copy a
substring of arg, don't you?

And we could do that (less efficiently) with something like
    match arg with
    | ss when string_starts_with ss "foo_" -> 
       let s = rest_of_string ss "foo_" in (* ..code_foo.. *)
    | ss when string_starts_with ss "bar_" -> 
       let s = rest_of_string ss "bar_" in (* ..code_foo.. *)

[the code of string_starts_with & rest_of_string is obvious]

Actually, a syntactic camlp4 trick could do the above



However, what would be great would be to be able to code 
  match arg with
    | "beef_" ^ s -> beef_case s
    | "gee_" ^ t -> gee_case t

and have the generated code factorize the common sub-test, that is that arg.[1] is 'e' and
arg.[2] is 'e' in both cases.

We don't have that, and we can't do that with syntactic preprocessing.



Cheers.

-- 
Basile STARYNKEVITCH         http://starynkevitch.net/Basile/
email: basile<at>starynkevitch<dot>net mobile: +33 6 8501 2359
8, rue de la Faiencerie, 92340 Bourg La Reine, France
*** opinions {are only mine, sont seulement les miennes} ***

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

end of thread, other threads:[~2011-09-17  8:16 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-14 20:16 [Caml-list] pattern matching on strings Walter Cazzola
2011-09-14 20:40 ` Basile Starynkevitch
2011-09-16 21:20   ` Richard W.M. Jones
2011-09-17  8:15     ` Basile Starynkevitch
2011-09-14 20:57 ` Philippe Veber
2011-09-14 21:44   ` Raphael Proust
2011-09-16 22:18     ` Philippe Veber
2011-09-14 21:14 ` Philippe Strauss

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).