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 6009B5D5 for ; Tue, 30 Jun 2020 18:07:47 +0000 (UTC) X-IronPort-AV: E=Sophos;i="5.75,298,1589234400"; d="scan'208,217";a="457515439" 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 20:07:45 +0200 Received: by sympa.inria.fr (Postfix, from userid 20132) id DCFFAE018C; Tue, 30 Jun 2020 20:07:45 +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 7C4A7E0129 for ; Tue, 30 Jun 2020 20:07:43 +0200 (CEST) Authentication-Results: mail2-smtp-roc.national.inria.fr; spf=None smtp.pra=jesse@haberkucharsky.com; spf=Pass smtp.mailfrom=hakuch@gmail.com; spf=None smtp.helo=postmaster@mail-wr1-f45.google.com IronPort-PHdr: =?us-ascii?q?9a23=3A9DeNxxWreP/0YPadC4AMmMaR7XDV8LGtZVwlr6E/?= =?us-ascii?q?grcLSJyIuqrYZRSCvKdThVPEFb/W9+hDw7KP9fy5BypYud3R7DhCKMUKC0ZYz5?= =?us-ascii?q?1O3kQJO42sMQXDNvnkbig3ToxpdWRO2DWFC3VTA9v0fFbIo3e/vnY4ExT7Mhdp?= =?us-ascii?q?dKyuQtaBx8u42Pqv9JLNfg5GmCSyYa9oLBWxsA7dqtQajZFtJ6osyxbFuGdEd/?= =?us-ascii?q?hZyW5rKl+YghLw6tut8JJ5/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/iih3I7pwxzpDWk28ciipPOhoIQ0l3K8Tt2wJ0uJd?= =?us-ascii?q?KmVUV1Y8SrH4BOuCGALod4R94iTH1ouCkg0L0Gop27fSgXw5kgxR7QdeeHc5OW?= =?us-ascii?q?7R/4VOaeOyx3i2x/eLK8mha97UigxffmVsmv01ZLrjBJncXLtnAIzhHe7NWMRf?= =?us-ascii?q?Rh8Em7wzmPyxzT5f9eIUAyjafWKp4vz74tm5cQsEnPAiz7lUX0gaGYaEgp+vWk?= =?us-ascii?q?5evpb7vmqZKRKY95hwDgPqgzhsGzHeQ2PAcPUmSG+umx1aDv8EvkS7tEif02l7?= =?us-ascii?q?PWsJHcJckDuK61GQBV3Zs75xakFTim1c4UnXwDLF9DZRmJjJDpNknQLPzkCfqz?= =?us-ascii?q?mVehnTdxy/zYILHtH4/BI3fDnbrnYL1z8VRTyBApwtBa/59UCq8OIPb0WkLpsd?= =?us-ascii?q?zXFB45Mwitz+fpEtVxy5oSWWyAD6KZKq/SvliI5uUgI+mIeoAZoiryK/8g5/L2?= =?us-ascii?q?jH85n0ESfbWx0JcJdHy1Gu5qLkaZbHb2nNsND3oGshAxQeHqkFGCVCRcZ3e2X6?= =?us-ascii?q?Iy/DE7D4emAJ/DRo+3g7yBwTu0Hp1Na2BJD1CDC3bod4GeV/gQbyKSJ9dtkiYY?= =?us-ascii?q?Wri5V48hyRauuRfmxLV9K+rU/jQUtZbi1Nhu++3ejgoy9DxxD8SFyW6BVWB0nm?= =?us-ascii?q?USRz83xq9zu0J9yk3QmZR/1sdREJRw+utESE9uLpfZ1+VwD9fxRxrMZP+RT026?= =?us-ascii?q?T9LgBzwtGJZ5ifoqK010HtHnihHYw2LqBLQckrjDCJ0v+b/HxDm7b5J2wnPCka?= =?us-ascii?q?0glEUOQ81VNGTgiLQppCbJAIucsUiCjKviVa0W0TSI13qIzWOUp0JJGFpyXL7e?= =?us-ascii?q?UFgfb0Hbt9fk7UPLVaStGPIsNQ4Xmp3KEbdDdtC81QYOf/zkItmLJj/owjbiNV?= =?us-ascii?q?Oz3rqJKbHSVSAY1STZBlIDlllKr3mDPAk6QCympjCHVWE8JRfUe0rptNJGhja7?= =?us-ascii?q?Q0szlVzYakRg0/+q4EdQi6DBDfwU2b0AtWEqrDAmRA/hjeKTMMKJok9aRIsZec?= =?us-ascii?q?k0ug8V1WvTuhZ+I5egJrp5hU9YeANy7Rvj?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0DLHABIfvtehi3dVdFgHQEBPAEFBQECA?= =?us-ascii?q?QkBgVYHAQMBgTsCgRRFVDMshDGBHI95k2+GGhOBcwEDAQwbDgYEAQGGdQIcBwE?= =?us-ascii?q?ENgQNAhABAQUBAQECAQMDBAETAQEBCAsLCCmFYgyCNymDDwEEARIRBEcQCwsLN?= =?us-ascii?q?wICIhIBBQEcBgESIoMEAYJcIKJegQQ9iyh/M4p3EoEkAgEBjGYaPgGBQYFHgiw?= =?us-ascii?q?uPoQDg1CCYASOfxmMboglkFWCZohJhiuKTiCCc4kthSGNVZFTnnAPI4FKCYFsM?= =?us-ascii?q?xoIGxU7MQaCMglHGQ2TZ4JIhlIoMBodAgYBBwEBAwmQJQEB?= X-IPAS-Result: =?us-ascii?q?A0DLHABIfvtehi3dVdFgHQEBPAEFBQECAQkBgVYHAQMBgTs?= =?us-ascii?q?CgRRFVDMshDGBHI95k2+GGhOBcwEDAQwbDgYEAQGGdQIcBwEENgQNAhABAQUBA?= =?us-ascii?q?QECAQMDBAETAQEBCAsLCCmFYgyCNymDDwEEARIRBEcQCwsLNwICIhIBBQEcBgE?= =?us-ascii?q?SIoMEAYJcIKJegQQ9iyh/M4p3EoEkAgEBjGYaPgGBQYFHgiwuPoQDg1CCYASOf?= =?us-ascii?q?xmMboglkFWCZohJhiuKTiCCc4kthSGNVZFTnnAPI4FKCYFsMxoIGxU7MQaCMgl?= =?us-ascii?q?HGQ2TZ4JIhlIoMBodAgYBBwEBAwmQJQEB?= X-IronPort-AV: E=Sophos;i="5.75,298,1589234400"; d="scan'208,217";a="457515416" X-MGA-submission: =?us-ascii?q?MDE2o9Hx6MjQAE++4ek58l9gDZ5RBKE4FuPW7p?= =?us-ascii?q?97KIjMW9DjBRM3Qg71e25jsHa60aB3E05fI2RxmG32WBO4hNzOtmFBJ7?= =?us-ascii?q?+Dmzm6S5sVJA7vrUpMUrqRvCq0g0LPDHEPc5D/RoMqzJ32k0xCEr9Qfy?= =?us-ascii?q?VRKcyPm3KUmQxRtuRG6lq8Zw=3D=3D?= Received: from mail-wr1-f45.google.com ([209.85.221.45]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/AES256-GCM-SHA384; 30 Jun 2020 20:07:42 +0200 Received: by mail-wr1-f45.google.com with SMTP id g18so21141234wrm.2 for ; Tue, 30 Jun 2020 11:07:42 -0700 (PDT) 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=oxbyCdd48nM8TnMWS+8FOh3HZ//cwbWyqdmjGirgwKQ=; b=lN+M0PkDNCVmG07y14Tc1BrHtUtSjNhFd119iCsOAw0MhbnpqWUCJm5uOZSL99EEPg GRrwz1MG6bT1bMGUrGDJQjzxtSkc/pnPMpwe5ynOXGqX7q7UqcU0jbPsmdwFiAV21ZuL 5w4HArmnEDAVpSL98XOXNZT0PBDTp3G1djNqjno81pw4eHNCYEu41sTU4YBblWs0+i3u 0N+AIZt7h/AcIHsY6saUJtYnfiSXdEKPhtWJBY/l4sTKZfN5keNem/XLV2RuOYYSm6lL fPTwbCkppRw1Gy9FDZzjzzdHfKZ9YsZPijOAGvZiF0fMJUId2gMMhpKAbw57GPGwpmuA j/Qg== X-Gm-Message-State: AOAM532kgoex9tswK8dzrrMYzyTPikaCkAVKS70bh2AY5kNCMaLaj7b1 +vnkMUdjykRXExnlHLF6Hmz+rfMPsEawWJ3lVahrhXW0XYc= X-Google-Smtp-Source: ABdhPJxLizpFVQ50JtcFR82VcbmffvCMemj1L+gD9nXgP4miDdIj/vsvGFtmECUwPe8bfZL5Nqm+3FAbkoqaH8bg/ZM= X-Received: by 2002:a5d:6288:: with SMTP id k8mr22271340wru.373.1593540461982; Tue, 30 Jun 2020 11:07:41 -0700 (PDT) MIME-Version: 1.0 References: <20200630162539.itp2j2xpdgyvaeif@posteo.net> In-Reply-To: <20200630162539.itp2j2xpdgyvaeif@posteo.net> From: Jesse Haber-Kucharsky Date: Tue, 30 Jun 2020 14:07:30 -0400 Message-ID: To: Sam Kuper , "ML caml-list (ocaml discuss)" Content-Type: multipart/alternative; boundary="0000000000002c0b7e05a9510d61" Subject: Re: [Caml-list] Restrict type to specific chars Reply-To: Jesse Haber-Kucharsky X-Loop: caml-list@inria.fr X-Sequence: 18188 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: --0000000000002c0b7e05a9510d61 Content-Type: text/plain; charset="UTF-8" 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. > Hi Sam. As a small variation of Yawar's excellent reply, consider the following (the file is named `sam.ml`): module AB : sig type t = private char val a : t val b : t val char : t -> char end = struct type t = char let a = 'a' let b = 'b' let char t = t end let () = let x = AB.a in let y = AB.b in assert (AB.char x = 'a') ; assert (AB.char y = 'b') I like this approach because it statically guarantees that a value of `Ab.t` is always either 'a' or 'b', and attempting to do otherwise results in a compilation error. Best, -- Jesse --0000000000002c0b7e05a9510d61 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable

On Tue, Jun 30, 2020 at 12:26 PM Sam Kupe= r <sampablokuper@posteo.net<= /a>> wrote:
D= ear 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.
=

Hi Sam.

As a smal= l variation of Yawar's excellent reply, consider the following (the fil= e is named `sam.ml`):

=C2=A0 =C2=A0 module AB : sig
=C2=A0 =C2=A0 =C2=A0 type t =3D private = char

=C2=A0 =C2=A0 =C2=A0 val a : t
=C2=A0 =C2=A0 =C2=A0 val b : = t
=C2=A0 =C2=A0 =C2=A0 val char : t -> char
=C2=A0 =C2=A0 end =3D = struct
=C2=A0 =C2=A0 =C2=A0 type t =3D char

=C2=A0 =C2=A0 =C2=A0 = let a =3D 'a'
=C2=A0 =C2=A0 =C2=A0 let b =3D 'b'
=C2= =A0 =C2=A0 =C2=A0 let char t =3D t
=C2=A0 =C2=A0 end

=C2=A0 =C2= =A0 let () =3D
=C2=A0 =C2=A0 =C2=A0 let x =3D AB.a in
=C2=A0 =C2=A0 = =C2=A0 let y =3D AB.b in
=C2=A0 =C2=A0 =C2=A0 assert (AB.char x =3D '= ;a') ;
=C2=A0 =C2=A0 =C2=A0 assert (AB.char y =3D 'b')
=

I like this approach because it statically guarantees t= hat a value of `Ab.t` is always either 'a' or 'b', and atte= mpting to do otherwise results in a compilation error.

Best,
--
Jesse
--0000000000002c0b7e05a9510d61--