* [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-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
* 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
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