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 ESMTPS id 947005D5 for ; Tue, 30 Jun 2020 17:34:10 +0000 (UTC) X-IronPort-AV: E=Sophos;i="5.75,298,1589234400"; d="scan'208,217";a="457511568" Received: from prod-listesu18.inria.fr (HELO sympa.inria.fr) ([128.93.162.160]) by mail2-relais-roc.national.inria.fr with ESMTP; 30 Jun 2020 19:33:40 +0200 Received: by sympa.inria.fr (Postfix, from userid 20132) id B2928E0172; Tue, 30 Jun 2020 19:33:40 +0200 (CEST) Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by sympa.inria.fr (Postfix) with ESMTPS id 75EC6E0129 for ; Tue, 30 Jun 2020 19:33:37 +0200 (CEST) Authentication-Results: mail3-smtp-sop.national.inria.fr; spf=None smtp.pra=yawar.amin@gmail.com; spf=Pass smtp.mailfrom=yawar.amin@gmail.com; spf=None smtp.helo=postmaster@mail-io1-f41.google.com IronPort-PHdr: =?us-ascii?q?9a23=3ACfAkwRVo1/vdLttvFNk7zo3BuoHV8LGtZVwlr6E/?= =?us-ascii?q?grcLSJyIuqrYZRSHvadThVPEFb/W9+hDw7KP9fy5BypYud3R6ThCKMUKC0ZYz5?= =?us-ascii?q?1O3kQJO42sMQXDNvnkbig3ToxpdWRO2DWFC3VTA9v0fFbIo3e/vnY4ExT7Mhdp?= =?us-ascii?q?dKyuQtaBx8u42Pqv9JLNfg5GmCSyYa9oLBWxsA7dqtQajZFtJ6osyxbFuGdEd/?= =?us-ascii?q?hZyW5rOF6YghLw6tut8JJ5/ClcpvIs+9RcXanmeqgzUKBVAikhP20p/sPgqAPN?= =?us-ascii?q?TRGI5nsSU2UWlgRHDg3Y5xzkXZn/rzX3uPNl1CaVIcP5Q7Y0WS+/76hwUx/nlD?= =?us-ascii?q?0HNz8i/27JjMF7kb9Wrwigpxx7xI7UfZ2VOf9jda7TYd8WWWxMVdtKWidfHo2z?= =?us-ascii?q?cZcAD+sZPeZZsYb9oUcOrQCjDgWoHe/j1yNEimPz0aA81OsvDBzG3Bc4H90QrH?= =?us-ascii?q?vUsNv7NKAXUe+vzanIyyjIY/dZ1Dr57YTFdA0qr/ORUrJqacfexkcvGAHFgFue?= =?us-ascii?q?qoLrIi2b2fgWvmeB8+ZtT/iih3I7pwxzpDWk28ciipPOhoIQ0l3L9z92wYgvKt?= =?us-ascii?q?2iVUV2fdukEJpWtyqHMIZ3QtktQm9ytyYg0LEJo5u7fCkMyJk8yB7fbuaIc4mM?= =?us-ascii?q?4h75SOmRJjJ4iWtjdbmiiBm87VKuxffgVsmozllKtCxFn8HQu3wTyhDe5MeJR/?= =?us-ascii?q?Rg8kq91ziDyR3e5v9aLU07laTXNZAvz6M/m5YOsUnNECz7lVvrgKKYeUgp+eyl?= =?us-ascii?q?5vj7brjnoJKXKoF6igb7Mqs0m8y/B/w1MhYUU2iU5Oux0qDo807hQLhSkPE6jq?= =?us-ascii?q?3UvIrZKMkbvKK1Hg5Y34c55xuwEjur1skTk2MdI1JfYh2HipDkO1HQL/D8Cvey?= =?us-ascii?q?m1Gsny1qx/DCJ7HhA5LNImXanLfvcrtx9lRQyAU0zdBY6JJUDq8OLOjvVU/2sd?= =?us-ascii?q?zUFh45MwqqzOb7ENhxyJ8SVGaVDqKaMK7eq0KE6+MuLuWWa4IZpS7xK/0/6P7v?= =?us-ascii?q?iX85l0Udfa6s3ZYPaHG3BPpnLF+DYXb2mNgBFGYKvgwlQezljV2NSz9TZ3KoU6?= =?us-ascii?q?0g4TE7DZqqDZ3fSYC1nLyBwCC7E4VKaW9cD1CMFW7kd4GFW/cXdCKfOdRhkzwB?= =?us-ascii?q?Vbi5UYAtzxCutAngy7pmNOXY4CMYtYiwnORystbakFkR6CR5FYzJyGiIV2h+mm?= =?us-ascii?q?QLWic7xohnpldhx1DF16Vk1bgQX/l3r/hAVwN/MZ/H06Q6DNv7XwaJctaSQ0u9?= =?us-ascii?q?WZTsSWU6R9c1htsPeFpVGtO4jxmF0TD8UJEPkLneNZUr+7iU9n3wIY4p2n/Z3b?= =?us-ascii?q?NnhlwnRONAMGSnguh08A2FVN2BqFmQi6v/LfdU5yXK7mrWiDfX5R0KYEtLSazA?= =?us-ascii?q?GEsnSA7Ot92gvxHNSravDfIsNQ4TkZfTeJsPUcXgiBB9fNmmPd3fZ2yrnGLpXE?= =?us-ascii?q?SHw7qNaMzhfGBPhXyAWnhBqBga+DO9DSZ7BiqlpDiDXjlnFFaqYkS1tOci8TW0?= =?us-ascii?q?SUg7ywzMZEpkheK4?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0CqBADUdvtegCmmVdFgHQEBAQEJARIBB?= =?us-ascii?q?QUBggoCglJFVDMshDGBHIJejRuLC4hkhi2BaAsBAwEMGw4GBAEBhEcCgiwCHAc?= =?us-ascii?q?BBDUFDQIQAQEFAQEBAgEDAwQBEwEBCQ0JCCeFZAyCNymDDwEBAwESEQQZARsSD?= =?us-ascii?q?AMBCwYFCzcCAiIBEQEFARwGARIigwWCSgEDDiCiX4EEPYsofxYFAReDAgWEeQo?= =?us-ascii?q?ZKA1iA4E0AgEGEoEmjGgPgUw/gUeCLC4+hANngmmCYASOfxmMbphSKAeCX4EHB?= =?us-ascii?q?AuNXopOIIJziS2FIY1VkVOecA8jgUiBdzMaI1AxgjhQGQ2OHoNxgViJGigwGh0?= =?us-ascii?q?CBgEHAQEDCZAlAQE?= X-IPAS-Result: =?us-ascii?q?A0CqBADUdvtegCmmVdFgHQEBAQEJARIBBQUBggoCglJFVDM?= =?us-ascii?q?shDGBHIJejRuLC4hkhi2BaAsBAwEMGw4GBAEBhEcCgiwCHAcBBDUFDQIQAQEFA?= =?us-ascii?q?QEBAgEDAwQBEwEBCQ0JCCeFZAyCNymDDwEBAwESEQQZARsSDAMBCwYFCzcCAiI?= =?us-ascii?q?BEQEFARwGARIigwWCSgEDDiCiX4EEPYsofxYFAReDAgWEeQoZKA1iA4E0AgEGE?= =?us-ascii?q?oEmjGgPgUw/gUeCLC4+hANngmmCYASOfxmMbphSKAeCX4EHBAuNXopOIIJziS2?= =?us-ascii?q?FIY1VkVOecA8jgUiBdzMaI1AxgjhQGQ2OHoNxgViJGigwGh0CBgEHAQEDCZAlA?= =?us-ascii?q?QE?= X-IronPort-AV: E=Sophos;i="5.75,298,1589234400"; d="scan'208,217";a="353188183" X-MGA-submission: =?us-ascii?q?MDEmBSInCAvuu+jW1GqT4xlTDy8QeQvJIBODJw?= =?us-ascii?q?AvYV5eBysWyK5GQ8M+wOivaTM9LGfaoGWJJsXxdL4NpEw2JRAJXFd40I?= =?us-ascii?q?R1uAS4M91O5Yx0AHl803vn+VmPFxbJLxHqyrB/F9SO7IXg6Koq1EHng6?= =?us-ascii?q?PsJMRDjrCO/26CPGtGCiDB9g=3D=3D?= Received: from mail-io1-f41.google.com ([209.85.166.41]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/AES256-GCM-SHA384; 30 Jun 2020 19:33:36 +0200 Received: by mail-io1-f41.google.com with SMTP id v6so8213002iob.4 for ; Tue, 30 Jun 2020 10:33:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to; bh=2X5ZTgIe3PKnA0IKWwMBI2mT+9ceIkK5VkvZQKnunMk=; b=niY8TVLzWv5JeRYu40EHOBed9oB2jI7QTaIPaT0bFRqBrnW9ktvfsWegbbYTZKy63a NK89ShUcCBEuJRKVAZoBn94touxxIHAuzrX5SUGBYAdoNCk0YLIqwHAHFm8nC/5/2oH/ pAZE3o7lNKRz1/zwBfFK0JziWNTy6iBz6h5YSQ4uk1dYYvt4OD130oP3fyaaCOnpaIeZ rHeGHJqk9sIiclxdGtXfdU4fQO4XSmZeBNaz7iwLtyg8TWuL3Q+TgWMfL8rXiSwrHPcB tPjYoZrtYbv+wEEz9LbU6AwUIDHURsCvOFSwTcBhwTNoSolTEPuJRzGHz8RNu1Yh75OM v7Aw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to; bh=2X5ZTgIe3PKnA0IKWwMBI2mT+9ceIkK5VkvZQKnunMk=; b=moQJDLZQNedLXn5VG4RF6oj47l5Fw1O03dTvAGK4sS5Q6Ojm1JCKl8LWS0o9yW4nhU 2z7k0iAaL6ixeswElN+eUUTGWpcV1FieqJYoTN4cDVUrF+ghxs+Ra3S7/Q0vE6XthJM/ gf80a6B9j2mtt1wK13cxPw5XMli1ltxCciJwqibtBOP8HGdLgWo1UK9MrYLG76nlJp1g EDsjuplBOU2rB5j/VENzPqibw45pTQmyvkkcYs5TBQ3N1yd0cs3Noes4K7nPv6XdN8Co L4ZUAxLYRv9IqjeyX+sVgCW0oS/SDB4bbZ8pX8DPh5rggL0RITyMKPReCyjLeQ3MfOD7 4vZQ== X-Gm-Message-State: AOAM530IY2YPRjyWzq1TxofF/RzJWIsilzukiQnJTSxdwx2kuW3xF9PK qZzTDWss+01hfvK2ODa8owCEK43qZUnzeBCFCg== X-Google-Smtp-Source: ABdhPJyxr9bpUWnHmxA5F6Ev0VAK5w/oW1AsqF81NEOaB7/+wz8EIBmCnEQCNCJXO63NOL6JURp0HiST12NwHEtx8sA= X-Received: by 2002:a05:6638:979:: with SMTP id o25mr24030665jaj.24.1593538414635; Tue, 30 Jun 2020 10:33:34 -0700 (PDT) MIME-Version: 1.0 References: <20200630162539.itp2j2xpdgyvaeif@posteo.net> In-Reply-To: <20200630162539.itp2j2xpdgyvaeif@posteo.net> From: Yawar Amin Date: Tue, 30 Jun 2020 13:33:23 -0400 Message-ID: To: Sam Kuper , "ML caml-list (ocaml discuss)" Content-Type: multipart/alternative; boundary="00000000000023f19a05a95093ba" Subject: Re: [Caml-list] Restrict type to specific chars Reply-To: Yawar Amin X-Loop: caml-list@inria.fr X-Sequence: 18186 Errors-To: caml-list-owner@inria.fr Precedence: list Precedence: bulk Sender: caml-list-request@inria.fr X-no-archive: yes List-Id: List-Help: List-Subscribe: List-Unsubscribe: List-Post: List-Owner: List-Archive: Archived-At: --00000000000023f19a05a95093ba Content-Type: text/plain; charset="UTF-8" Hi Sam, You can't do exactly that, because OCaml values like chars don't exist at the type level. So you can't say e.g. let a : 'a' = a ...or other similar things where values would be types. What you would usually do is make an abstract (or private) type that allows constructing only valid values. E.g., module Ab : sig type t = private char val make : char -> t option end = struct type t = char let make char = match char with 'a' | 'b' -> Some char | _ -> None end This allows constructing only values containing 'a' or 'b', with the guarantee provided by the module's implementation. So if you call `Ab.make some_char`, you'll get back an `Ab.t option`, but if it's `Some`, then you have a guarantee that it contains 'a' or 'b'. You can convert the `Ab.t` value to a `char` using `(value :> char)` (basically, upcasting). Regards, Yawar On Tue, Jun 30, 2020 at 12:26 PM Sam Kuper wrote: > Dear list, > > Forgive me for asking a very basic question, but I have not so far been > able to find an answer in any of the OCaml books to which I have access, > nor in the OCaml documentation or mailing list archive. > > How does one define a type whose values are restricted to one of some > specified chars? > > E.g. suppose I want to define a type `ab` whose values can only be > either 'a' or 'b'. I imagine that should work something like this: > > # type ab = Ab of char 'a' | Ab of char 'b' ;; > type ab = Ab of char 'a' | Ab of char 'b' > > and thereby give the following functionality: > > # Ab 'a';; > - : ab = Ab 'a' > # Ab 'b';; > - : ab = Ab 'b' > # Ab 'c';; > Error: > > The definition above is essentially pseudo-code to illustrate what I > would like to achieve with real, valid OCaml code. (If I knew how to > write valid OCaml to achieve this, then I would not be posting this > question on the mailing list.) > > Here are several of my failed attempts at writing OCaml code for what I > want to achieve: > > # type ab = 'a' | 'b';; > Error: Syntax error > > # type ab = char 'a' | char 'b';; > Error: Syntax error > > # type ab = Ab of char 'a' | Ab of char 'b';; > Error: Syntax error > > # type 'a ab = 'a constraint 'a = 'a' | 'b';; > Error: Syntax error > > # type 'a ab = 'a constraint 'a = 'a' | 'a = 'b';; > Error: Syntax error > > How can I actually achieve it? > > Thank you in advance, > > Sam > > -- > A: When it messes up the order in which people normally read text. > Q: When is top-posting a bad thing? > > () ASCII ribbon campaign. Please avoid HTML emails & proprietary > /\ file formats. (Why? See e.g. https://v.gd/jrmGbS ). Thank you. > --00000000000023f19a05a95093ba Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi Sam,

You can't do exactly that, = because OCaml values like chars don't exist at the type level. So you c= an't say e.g.

=C2=A0 =C2=A0 let a : 'a'= ; =3D a

...or other similar things where values wo= uld be types.

What you would usually do is make an= abstract (or private) type that allows constructing only valid values. E.g= .,

=C2=A0 =C2=A0 module=C2=A0Ab : sig
= =C2=A0 =C2=A0 =C2=A0 type t =3D private char
=C2=A0 =C2=A0 =C2=A0= val make : char -> t option
=C2=A0 =C2=A0 end =3D struct<= br>
=C2=A0 =C2=A0 =C2=A0 type t =3D char
=C2=A0 =C2= =A0 =C2=A0 let make char =3D match char with 'a' | 'b' ->= ; Some char | _ -> None
=C2=A0 =C2=A0 end
This allows constructing only values containing 'a' or= 'b', with the guarantee provided by the module's implementatio= n. So if you call `Ab.make some_char`, you'll get back an `Ab.t option`= , but if it's `Some`, then you have a guarantee that it contains 'a= ' or 'b'.

You can convert the `Ab.t` v= alue to a `char` using `(value :> char)` (basically, upcasting).

Regards,

Yawar

On Tue, Jun = 30, 2020 at 12:26 PM Sam Kuper <sampablokuper@posteo.net> wrote:
Dear list,

Forgive me for asking a very basic question, but I have not so far been
able to find an answer in any of the OCaml books to which I have access, nor in the OCaml documentation or mailing list archive.

How does one define a type whose values are restricted to one of some
specified chars?

E.g. suppose I want to define a type `ab` whose values can only be
either 'a' or 'b'.=C2=A0 I imagine that should work somethi= ng like this:

=C2=A0 =C2=A0 # type ab =3D Ab of char 'a' | Ab of char 'b'= ;;
=C2=A0 =C2=A0 type ab =3D Ab of char 'a' | Ab of char 'b'
and thereby give the following functionality:

=C2=A0 =C2=A0 # Ab 'a';;
=C2=A0 =C2=A0 - : ab =3D Ab 'a'
=C2=A0 =C2=A0 # Ab 'b';;
=C2=A0 =C2=A0 - : ab =3D Ab 'b'
=C2=A0 =C2=A0 # Ab 'c';;
=C2=A0 =C2=A0 Error: <some error>

The definition above is essentially pseudo-code to illustrate what I
would like to achieve with real, valid OCaml code.=C2=A0 (If I knew how to<= br> write valid OCaml to achieve this, then I would not be posting this
question on the mailing list.)

Here are several of my failed attempts at writing OCaml code for what I
want to achieve:

=C2=A0 =C2=A0 # type ab =3D 'a' | 'b';;
=C2=A0 =C2=A0 Error: Syntax error

=C2=A0 =C2=A0 # type ab =3D char 'a' | char 'b';;
=C2=A0 =C2=A0 Error: Syntax error

=C2=A0 =C2=A0 # type ab =3D Ab of char 'a' | Ab of char 'b'= ;;
=C2=A0 =C2=A0 Error: Syntax error

=C2=A0 =C2=A0 # type 'a ab =3D 'a constraint 'a =3D 'a'= | 'b';;
=C2=A0 =C2=A0 Error: Syntax error

=C2=A0 =C2=A0 # type 'a ab =3D 'a constraint 'a =3D 'a'= | 'a =3D 'b';;
=C2=A0 =C2=A0 Error: Syntax error

How can I actually achieve it?

Thank you in advance,

Sam

--
A: When it messes up the order in which people normally read text.
Q: When is top-posting a bad thing?

()=C2=A0 ASCII ribbon campaign. Please avoid HTML emails & proprietary<= br> /\=C2=A0 file formats. (Why? See e.g. https://v.gd/jrmGbS ). Thank you.
--00000000000023f19a05a95093ba--