* [Caml-list] pattern matching on mapped lists [not found] <20150602100015.E87D67EEF7@sympa.inria.fr> @ 2015-06-02 22:23 ` Nils Becker 2015-06-03 16:52 ` Romain Bardou 2015-06-03 16:58 ` John Whitington 0 siblings, 2 replies; 5+ messages in thread From: Nils Becker @ 2015-06-02 22:23 UTC (permalink / raw) To: caml-list I find this syntax handy let [ii; jj] = List.map float_of_int [i; j] in ... do stuff with the floats because it avoids repeating the function call. The compiler lets this pass but warns that the matching is not exhaustive since [] is not matched. This actually can't happen if I'm not mistaken. So, is this considered good style, or is there a better idiomatic way to do multiple assignments? If yes, should this be an enhancement request for the type checker? n. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] pattern matching on mapped lists 2015-06-02 22:23 ` [Caml-list] pattern matching on mapped lists Nils Becker @ 2015-06-03 16:52 ` Romain Bardou 2015-06-03 17:42 ` Mikhail Mandrykin 2015-06-03 16:58 ` John Whitington 1 sibling, 1 reply; 5+ messages in thread From: Romain Bardou @ 2015-06-03 16:52 UTC (permalink / raw) To: caml-list On 03/06/2015 00:23, Nils Becker wrote: > I find this syntax handy > > let [ii; jj] = List.map float_of_int [i; j] in > ... do stuff with the floats > > because it avoids repeating the function call. The compiler lets this > pass but warns that the matching is not exhaustive since [] is not > matched. This actually can't happen if I'm not mistaken. So, is this > considered good style, or is there a better idiomatic way to do multiple > assignments? If yes, should this be an enhancement request for the type > checker? > > n. The type-checker cannot find out that List.map returns a list of the same size. I think it would require dependent types. Maybe some GADT can encode this, but it would be a bit messy. If you use this idiom often, maybe you should define some map functions on tuples, whose length is known at compile-time: let map2 f (x, y) = f x, f y let (ii, jj) = map2 float_of_int (i, j) in ... Unfortunately you need to define map2, map3, map4... Cheers, -- Romain ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] pattern matching on mapped lists 2015-06-03 16:52 ` Romain Bardou @ 2015-06-03 17:42 ` Mikhail Mandrykin 2015-06-03 18:06 ` Octachron 0 siblings, 1 reply; 5+ messages in thread From: Mikhail Mandrykin @ 2015-06-03 17:42 UTC (permalink / raw) To: caml-list On 06/03/2015 07:52 PM, Romain Bardou wrote: > On 03/06/2015 00:23, Nils Becker wrote: >> I find this syntax handy >> >> let [ii; jj] = List.map float_of_int [i; j] in >> ... do stuff with the floats >> >> because it avoids repeating the function call. The compiler lets this >> pass but warns that the matching is not exhaustive since [] is not >> matched. This actually can't happen if I'm not mistaken. So, is this >> considered good style, or is there a better idiomatic way to do multiple >> assignments? If yes, should this be an enhancement request for the type >> checker? >> >> n. > > The type-checker cannot find out that List.map returns a list of the > same size. I think it would require dependent types. Maybe some GADT > can encode this, but it would be a bit messy. > > If you use this idiom often, maybe you should define some map > functions on tuples, whose length is known at compile-time: > > let map2 f (x, y) = f x, f y > > let (ii, jj) = map2 float_of_int (i, j) in > ... > > Unfortunately you need to define map2, map3, map4... > > Cheers, > It seems GADT encoding mostly works here, but the absence of local opens in patterns and redefinition of [] constructor and [_; _] special syntax for lists currently makes the use of such encoding inconvenient e.g.: module Flist = struct type z = Z type 'a s = S of 'a type ('a, _) t = | Nil : ('a, z) t | :: : 'a * ('a, 'b) t -> ('a, 'b s) t let rec map : type a. _ -> (_, a) t -> (_, a) t = fun f -> function | Nil -> Nil | x :: xs -> f x :: map f xs end open Flist let a :: b :: c :: Nil = map ((+) 2) @@ 1 :: 2 :: 3 :: Nil;; (* Can't use Flist.[a; b; c] on both sides *) let d :: e :: Nil = map ((^) "2 + ") @@ "1" :: "2" :: Nil;; let g :: Nil = map ((+) 2) @@ 1 :: Nil;; Printf.printf "%d = %s = %d\n%!" a d g;; BTW, both features are already proposed as feature requests: https://github.com/ocaml/ocaml/pull/187 https://github.com/ocaml/ocaml/pull/76 Regards, Mikhail -- Mikhail Mandrykin Linux Verification Center, ISPRAS web: http://linuxtesting.org e-mail: mandrykin@ispras.ru ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] pattern matching on mapped lists 2015-06-03 17:42 ` Mikhail Mandrykin @ 2015-06-03 18:06 ` Octachron 0 siblings, 0 replies; 5+ messages in thread From: Octachron @ 2015-06-03 18:06 UTC (permalink / raw) To: caml-list On 06/03/15 19:42, Mikhail Mandrykin wrote: > It seems GADT encoding mostly works here, but the absence of local > opens in patterns and redefinition of [] constructor and [_; _] > special syntax for lists currently makes the use of such encoding > inconvenient e.g.: > > module Flist = > struct > > type z = Z > > type 'a s = S of 'a > > type ('a, _) t = > | Nil : ('a, z) t > | :: : 'a * ('a, 'b) t -> ('a, 'b s) t > > let rec map : type a. _ -> (_, a) t -> (_, a) t = fun f -> > function > | Nil -> Nil > | x :: xs -> f x :: map f xs > end > > open Flist > > let a :: b :: c :: Nil = map ((+) 2) @@ 1 :: 2 :: 3 :: Nil;; (* > Can't use Flist.[a; b; c] on both sides *) > > let d :: e :: Nil = map ((^) "2 + ") @@ "1" :: "2" :: Nil;; > > let g :: Nil = map ((+) 2) @@ 1 :: Nil;; > > Printf.printf "%d = %s = %d\n%!" a d g;; > > BTW, both features are already proposed as feature requests: > https://github.com/ocaml/ocaml/pull/187 > https://github.com/ocaml/ocaml/pull/76 > > Regards, Mikhail > A possibility to lighten these constructions is to use a ppx extension to rewrite the special syntax [a;...] into a standard Cons(a,... Nil)...) construction. For instance with my experimental ppx_listlike extension (https://github.com/Octachron/ppx_listlike), these examples can be rewritten as let [%ll? [a; b; c] ] = map ((+) 2) [%ll 1; 2; 3 ];; or with more syntactic sugar let%with_ll [ d; e ] = map ((^) "2 + ") ["1"; "2" ];; let%with_ll [g] = map ((+) 2) [1];; Regards, octachron. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] pattern matching on mapped lists 2015-06-02 22:23 ` [Caml-list] pattern matching on mapped lists Nils Becker 2015-06-03 16:52 ` Romain Bardou @ 2015-06-03 16:58 ` John Whitington 1 sibling, 0 replies; 5+ messages in thread From: John Whitington @ 2015-06-03 16:58 UTC (permalink / raw) To: Nils Becker; +Cc: caml-list Hi Nils, Nils Becker wrote: > I find this syntax handy > > let [ii; jj] = List.map float_of_int [i; j] in > ... do stuff with the floats > > because it avoids repeating the function call. The compiler lets this > pass but warns that the matching is not exhaustive since [] is not > matched. This actually can't happen if I'm not mistaken. So, is this > considered good style, or is there a better idiomatic way to do multiple > assignments? If yes, should this be an enhancement request for the type > checker? If the lengths are almost always small, why not just put appropriate functions map_pair, map_tuple3, map_tuple4 etc. into your library? fun map_tuple3 f (x, y, z) = (f x, f y, f z) let (ii, jj) = map_pair float_of_int (i, j) Or, even... let ii, jj = map_pair float (i, j) ...if you really want to save typing. John -- John Whitington Director, Coherent Graphics Ltd http://www.coherentpdf.com/ ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2015-06-03 18:06 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- [not found] <20150602100015.E87D67EEF7@sympa.inria.fr> 2015-06-02 22:23 ` [Caml-list] pattern matching on mapped lists Nils Becker 2015-06-03 16:52 ` Romain Bardou 2015-06-03 17:42 ` Mikhail Mandrykin 2015-06-03 18:06 ` Octachron 2015-06-03 16:58 ` John Whitington
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox