From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by c5ff346549e7 (Postfix) with ESMTP id 502D25D6 for ; Fri, 9 Aug 2019 14:56:53 +0000 (UTC) X-IronPort-AV: E=Sophos;i="5.64,364,1559512800"; d="scan'208,217";a="394971369" Received: from sympa.inria.fr ([193.51.193.213]) by mail2-relais-roc.national.inria.fr with ESMTP; 09 Aug 2019 16:56:52 +0200 Received: by sympa.inria.fr (Postfix, from userid 20132) id 7C9457EF0B; Fri, 9 Aug 2019 16:56:52 +0200 (CEST) Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id 2C1E17ED21 for ; Fri, 9 Aug 2019 16:56:47 +0200 (CEST) Authentication-Results: mail2-smtp-roc.national.inria.fr; spf=None smtp.pra=frederic.bour@lakaban.net; spf=Pass smtp.mailfrom=frederic.bour@lakaban.net; spf=None smtp.helo=postmaster@mail.lakaban.net IronPort-PHdr: =?us-ascii?q?9a23=3A1mQwoBA1XHLf2KHQKyZYUyQJP3N1i/DPJgcQr6Af?= =?us-ascii?q?oPdwSPT5p8bcNUDSrc9gkEXOFd2Cra4d0ayP6v+rBj1IyK3CmUhKSIZLWR4BhJ?= =?us-ascii?q?detC0bK+nBN3fGKuX3ZTcxBsVIWQwt1Xi6NU9IBJS2PAWK8TW94jEIBxrwKxd+?= =?us-ascii?q?KPjrFY7OlcS30P2594HObwlSizexfK1+IA+roQnMtMQajolvJ6IswRbVv3VEfP?= =?us-ascii?q?hby3l1LlyJhRb84cmw/J9n8ytOvv8q6tBNX6bncakmVLJUFDspPXw7683trhnD?= =?us-ascii?q?UBCA5mAAXWUMkxpHGBbK4RfnVZrsqCT6t+592C6HPc3qSL0/RDqv47t3RBLulS?= =?us-ascii?q?wKLCAy/n3JhcNsjaJbuBOhqAJ5w47Ie4GeKf5ycrrAcd8GWWZNW8BcXDFDDIyh?= =?us-ascii?q?dYsCF+UOPehaoIf9qVUArgawCxewC+700DBEmmX70Lcm3+g9EwzL2hErEdIUsH?= =?us-ascii?q?TTqdX4LKccUfqvy6bV1zLDdfJW1ivg44XVdRAhvOuMVq93fMrf00kgCR7KgUuK?= =?us-ascii?q?qYzkIzyZzP8Cs2+G7+p6Tu+vj3QoqwJrrTe03MgsjJPFhoQLxVDY7Ch0xps+K9?= =?us-ascii?q?6gSENjf9KoDZVduzuEO4Z2X88uWXxktSU6x7EcpJK2fzQGxIw5yxLDb/GLaYuF?= =?us-ascii?q?7xL5WOqMIDp1hmhpdb2wihu07EOu0PfzVtOu31ZPtidFksfDtnQK1xHL78iIUP?= =?us-ascii?q?p9/kO71TaLzQ/T6ftLLlsumqrdMZIhxKA/loYLvUTCGC/5hln2gbeIekk59OWk?= =?us-ascii?q?8frrb7X7qpOGKoN5iQHzPr4zlsG8Heg0Kg0OUHKa+eS42r3j50r5QLBSg/04iK?= =?us-ascii?q?nWro3VKtoBpq64HwBZyJ0s6xGiDze8y9kYmWMILFFfdx2clYfpPUvCIPbmAvej?= =?us-ascii?q?m1isiitkx+jaPr39BZXANmTMn63kfbZ58kJczAszzctD559PEbEAIPfzWlfru9?= =?us-ascii?q?DCDx85NRa0w+f9B9ln2IMeQzHHPqjMepnTul+B/O5nHK+pIsc3vzDwMLJts+Tv?= =?us-ascii?q?hn8RkFkbcLmo1N0Qcn/uTdp8JEDMT2BtjlYbEGxClA0jVqS+hkePXTNJZn30Va?= =?us-ascii?q?Uh/Bk/AYGvB47FAIagnOrSj2+AApRKazUeWRi3GnDyetDBAq9UMXPAEopaijUB?= =?us-ascii?q?EIOZZcok3BCquhX9zuM8fO7d+SQSvJSl0tVptbSKyEMCsAdsBsHY6FmjCmF5mm?= =?us-ascii?q?RRF20z1aF750h0yV6J2K4+hfFER4QKu6F5FzwiPJuZ9NRUTsjoU1uaLNOAS1+s?= =?us-ascii?q?S9PgBzwtHIo8?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0ARAQB0iE1d/7S5+9VmHQEBBQEHBQGBV?= =?us-ascii?q?gUBCwGDViASKoQegR2HX4g4ilaIMYgDCQEDAQwvAQGEPwKCfAcBBDMGDgEEAQE?= =?us-ascii?q?EAQEEAQMHAWyFJwyCOikBgmcBBAEjBBkBATcBBAsLBAc3AgIiEgEFARwGE4UeD?= =?us-ascii?q?wSfYjyKMHJ/M4J6AQEFhjeBBwmBNAGKRoMzhCM+h0+CWJ0djT9tBwKCH5QvG5g?= =?us-ascii?q?4pWkPIYFFIoFYTS5FMQaCNYJCiEuFfD0zjw8BAQ?= X-IPAS-Result: =?us-ascii?q?A0ARAQB0iE1d/7S5+9VmHQEBBQEHBQGBVgUBCwGDViASKoQ?= =?us-ascii?q?egR2HX4g4ilaIMYgDCQEDAQwvAQGEPwKCfAcBBDMGDgEEAQEEAQEEAQMHAWyFJ?= =?us-ascii?q?wyCOikBgmcBBAEjBBkBATcBBAsLBAc3AgIiEgEFARwGE4UeDwSfYjyKMHJ/M4J?= =?us-ascii?q?6AQEFhjeBBwmBNAGKRoMzhCM+h0+CWJ0djT9tBwKCH5QvG5g4pWkPIYFFIoFYT?= =?us-ascii?q?S5FMQaCNYJCiEuFfD0zjw8BAQ?= X-IronPort-AV: E=Sophos;i="5.64,364,1559512800"; d="scan'208,217";a="394971347" X-MGA-submission: =?us-ascii?q?MDFHBtW/8ekZkt9DHs7Jc0+A9ngq3YdAGtZUfc?= =?us-ascii?q?OiHMRddyq++0NHnUd1pgCiQ4zmKIhmKojOKIlH7eJUoPf8UlscpK55VH?= =?us-ascii?q?s+dwaHXvfXKKgNjmgynPvFVEcQYlO9dJJ5IhMfMLZkd2M8MO+A10WYHn?= =?us-ascii?q?Qux9kgmbv0E7QsjwXqDZUR/w=3D=3D?= Received: from lakaban.net (HELO mail.lakaban.net) ([213.251.185.180]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Aug 2019 16:56:46 +0200 Received: from mail-lf1-f44.google.com (mail-lf1-f44.google.com [209.85.167.44]) (Authenticated sender: defre@ygg-drasil.fr) by mail.lakaban.net (Postfix) with ESMTPSA id B0E3AC60348 for ; Fri, 9 Aug 2019 16:56:45 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=lakaban.net; s=default; t=1565362605; bh=Qi+a+PWZkNw/ptgkiVwXNjGceIK2P7FyHnaK+TtcCI0=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=dCReoDtJp5VrG6gLzQskuIIx5n0buvnPh2XKBeTwFJXnkkvK/WLtO1GDYq6cNqPKX g/ouvIvfX9r6npTtQsAVkchaBTgn14rq5ZAu94cRBDiuKJpAlzaK0Hx1Kcg488KjIk esDJFlSZbHbu8DdGBQvSocGIzASiUihHZALyxjys= Received: by mail-lf1-f44.google.com with SMTP id v16so15865475lfg.11 for ; Fri, 09 Aug 2019 07:56:45 -0700 (PDT) X-Gm-Message-State: APjAAAW+zLwEqaVUXzaBj6hRdKNdyOcMl8HefWlE4YrOl/7nLAhi7QyM hwJzG+6bqBpws7Nt97KDLnvESv5TDIy1uLo1oCo= X-Google-Smtp-Source: APXvYqx4CScL90O89vwH2uxonvlTyQpaPQZut7ngOVFsrHlItGPIS+XZtafO0TvRGnoGH8LMKG7R9XnoCZmyTy55RNk= X-Received: by 2002:ac2:410e:: with SMTP id b14mr4614954lfi.123.1565362604892; Fri, 09 Aug 2019 07:56:44 -0700 (PDT) MIME-Version: 1.0 References: <20190809142719.ff4kogz4fq6r7vfr@annexia.org> In-Reply-To: <20190809142719.ff4kogz4fq6r7vfr@annexia.org> From: =?UTF-8?B?RnLDqWTDqXJpYyBCb3Vy?= Date: Fri, 9 Aug 2019 16:56:33 +0200 X-Gmail-Original-Message-ID: Message-ID: To: "Richard W.M. Jones" Cc: caml-list@inria.fr Content-Type: multipart/alternative; boundary="0000000000000268c6058fb06213" Subject: Re: [Caml-list] Syntax puzzle / suggestion Reply-To: =?UTF-8?B?RnLDqWTDqXJpYyBCb3Vy?= X-Loop: caml-list@inria.fr X-Sequence: 17755 Errors-to: caml-list-owner@inria.fr Precedence: list Precedence: bulk Sender: caml-list-request@inria.fr X-no-archive: yes List-Id: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: --0000000000000268c6058fb06213 Content-Type: text/plain; charset="UTF-8" Abusing list notations and GADTs to keep track of length and ensure exhaustive matching: module M = struct type ('a, 'b) t = [] : (_, unit) t | (::) : 'a * ('a, 'b) t -> ('a, unit * 'b) t end;; let rec to_list : type a b. (a, b) M.t -> a list = function | M.[] -> [] | M.(x :: xs) -> x :: to_list xs;; let decompose x = (to_list x, x);; # let all_items, M.[item1; item2] = decompose M.["hello"; "world"];; val all_items : string list = ["hello"; "world"] val item1 : string = "hello" val item2 : string = "world" On Fri, Aug 9, 2019 at 4:27 PM Richard W.M. Jones wrote: > Let's imagine you have a list of named things, but you also want to > collect them up into a single list. For example: > > let item1 = "hello" > let item2 = "world" > let all_items = [ item1; item2 ] > > let () = > printf "item1 = %s\n" item1; > printf "all_items = %s\n" (String.concat ", " all_items) > > This is fine, but there's a danger that a programmer could add item3 > but forget to add it to the "all_items" list. (In the real world > problem to which this applies, my items are complex and lengthy > structures, and the "all-things-list" is well off the bottom of the > page when you're viewing the top item). > > My idea to fix this was to write: > > let all_items = [ > ("hello" as item1); > ("world" as item2); > ] > > Actually I was slightly surprised to find this doesn't compile. I > guess because "as" can only be used like this in patterns, not > expressions. Also the scoping is wrong because the "as item1" if it > worked probably wouldn't apply outside the list. > > I haven't worked out if it's possible to write this in ordinary OCaml, > although I suppose ppx could solve it. Any ideas if this is possible? > > Rich. > --0000000000000268c6058fb06213 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Abusing list notations and GADTs to keep track of len= gth and ensure exhaustive matching:

module M =3D s= truct type ('a, 'b) t =3D [] : (_, unit) t | (::) : 'a * ('= a, 'b) t -> ('a, unit * 'b) t end;;
let rec to_lis= t : type a b. (a, b) M.t -> a list =3D function | M.[] -> [] | M.(x := : xs) -> x :: to_list xs;;
let decompose x =3D (to_list x, x);= ;

# let all_items, M.[item1; item2] =3D decompose = M.["hello"; "world"];;
val all_items : string list = =3D ["hello"; "world"]
val item1 : string =3D "= hello"
val item2 : string =3D "world"

On Fri, Aug 9,= 2019 at 4:27 PM Richard W.M. Jones <rich@annexia.org> wrote:
Let's imagine you have a list of named things, but you= also want to
collect them up into a single list.=C2=A0 For example:

=C2=A0 let item1 =3D "hello"
=C2=A0 let item2 =3D "world"
=C2=A0 let all_items =3D [ item1; item2 ]

=C2=A0 let () =3D
=C2=A0 =C2=A0 printf "item1 =3D %s\n" item1;
=C2=A0 =C2=A0 printf "all_items =3D %s\n" (String.concat ", = " all_items)

This is fine, but there's a danger that a programmer could add item3 but forget to add it to the "all_items" list.=C2=A0 (In the real = world
problem to which this applies, my items are complex and lengthy
structures, and the "all-things-list" is well off the bottom of t= he
page when you're viewing the top item).

My idea to fix this was to write:

=C2=A0 let all_items =3D [
=C2=A0 =C2=A0 ("hello" as item1);
=C2=A0 =C2=A0 ("world" as item2);
=C2=A0 ]

Actually I was slightly surprised to find this doesn't compile.=C2=A0 I=
guess because "as" can only be used like this in patterns, not expressions.=C2=A0 Also the scoping is wrong because the "as item1&quo= t; if it
worked probably wouldn't apply outside the list.

I haven't worked out if it's possible to write this in ordinary OCa= ml,
although I suppose ppx could solve it.=C2=A0 Any ideas if this is possible?=

Rich.
--0000000000000268c6058fb06213--