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 247E35D5 for ; Tue, 30 Jun 2020 17:55:18 +0000 (UTC) X-IronPort-AV: E=Sophos;i="5.75,298,1589234400"; d="scan'208";a="457513491" 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:55:15 +0200 Received: by sympa.inria.fr (Postfix, from userid 20132) id 718FFE018E; Tue, 30 Jun 2020 19:55:15 +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 2C428E0129 for ; Tue, 30 Jun 2020 19:55:12 +0200 (CEST) Authentication-Results: mail3-smtp-sop.national.inria.fr; spf=None smtp.pra=yotambarnoy@gmail.com; spf=Pass smtp.mailfrom=yotambarnoy@gmail.com; spf=None smtp.helo=postmaster@mail-ot1-f49.google.com IronPort-PHdr: =?us-ascii?q?9a23=3AuGmykBHGwEJ6laWYhoyF2p1GYnF86YWxBRYc798d?= =?us-ascii?q?s5kLTJ7yosuwAkXT6L1XgUPTWs2DsrQY0rSQ6/irCTBIoc7Y9ixbLdoUD15NoP?= =?us-ascii?q?5VtjRoONSCB0z/IayiRA0BN+MGamVY+WqmO1NeAsf0ag6aiHSz6TkPBke3blIt?= =?us-ascii?q?daz6FYHIksu4yf259YHNbAVUnjq9Zq55IAmroQnLucQanIpvJrwtxhfVrXdFeO?= =?us-ascii?q?tbzn5sKV6Pghrw/Mi98INj/ihKp/4t68tMWrjmcqolSrBVEC4oOH0v6s3xshnD?= =?us-ascii?q?QwqP5n8CXWgTjxFFHQvL4gzkU5noqif1ufZz1yecPc3tULA7Qi+i4LtxSB/pky?= =?us-ascii?q?gIKTg0+3zKh8NqjaJbpBWhpwFjw4PRfYqYOuZycr/bcNgHXmdKQNpfWDJdDYO9?= =?us-ascii?q?d4sPDvQOPeBEr4nmulACqQKyCRSwCO/zzzNFgHj507An0+Q6CQHJwhAvH84Avn?= =?us-ascii?q?TTqdX6LqYSUeaox6XMwjjOa/Za1DHg44bKbx8hu+mBUr1+ccXTyUchGQDLgEiO?= =?us-ascii?q?p4P5MD2YzfgNs3GB4uZ8Se6jl2wqpgdsqTav3McsjYzJi5oXxVDD6SV22oM1Ls?= =?us-ascii?q?ClRUFhe96kFpxQtiGHPIZxQsIiRH1otzw/yrIdo5G7Zi4KyJMnxhPEZPyHdpKH?= =?us-ascii?q?4hPnVOqLPTh4g3dldau5ih2v/keu1vfyWdOo0FZWsCVFiN/Mu2gC2hHQ9MWKSP?= =?us-ascii?q?Rz81m91TuOywze5OFKLE83mKfbL5Ms3L09m5QPvUnBACL6hEr4ga6We0gn+uWm?= =?us-ascii?q?5erpb6viq5KcMYJ/lw/wMqMrmsOlAOQ4NBADX3aB9eSzybLu+1DyTrZSjvAujK?= =?us-ascii?q?XVrJTXKd4Yq6O5GQNZzJsv5wqlAzqp1NkVm2QMIkhfdxKdlYfpPknDIPDmAve7?= =?us-ascii?q?hFShiDJryOrHPr3lG5nNKWTDnKr4cbZz5ENRzBA/zd9Y55JTBbEBJOz8VlXtu9?= =?us-ascii?q?zfCx81Kw20w+D5B9Vhzo4SR36DD6uDPK7RsVKE/PwjL/SQaIMPtzvwL+Ap5/v0?= =?us-ascii?q?gn84nV8dc7Op3ZwSaH2gHvVmJFmZbmDpgtgaC2gKpAw+TOvqiVCZXj5TYmy9X6?= =?us-ascii?q?M45j0hFI2mCoLDSpi3gLOdxCe7AoFWZmdeB1+QC3jocoGEV+4IaCKTOc9hjicJ?= =?us-ascii?q?VaOhSo8kzRGhrhX2y7thLurO+y0Xr4jv1NZv576bqRZnxDVrBt7V+mSMSSkgj2?= =?us-ascii?q?oXTiVw1aV+p2Ryz16C1e5zhPkORvJJ4PYcYwAmPJuU5eVgDdfjElbQecuATVyv?= =?us-ascii?q?WNOhEBk+S9swx5kFZEMrSIbqtQzKwyf/W+xdrLeMHpFht/+FhimjF4NG03/DkZ?= =?us-ascii?q?IZoRwjS8pLO3ehg/cmpQfWDo/N1U6ekvTzLPlO7Gv27G6GiFG2kgRYXQp3C/iX?= =?us-ascii?q?WHkeYg7RsY286B+TCbCpDrsjP01KzsvQcvIWOO2stk1PQbLYAPqbe3i4wj7iCh?= =?us-ascii?q?OBx7fKZ43vKT0Q?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0AXAgBke/tehjHSVdFgHAEBAQEBAQcBA?= =?us-ascii?q?RIBAQQEAQFAgUqCVEVUMxcVhDGDeo0bmhyBaAsBAwEMGw4GBAEBhEcCgiwCHAc?= =?us-ascii?q?BBDQTAhABAQUBAQECAQMDBAETAQEBCAsLCCmFYgyCNymDDwEBBBIRBBkBGxILA?= =?us-ascii?q?QMMBgULDQICJgICIQEBEQEFARwGEyKDBAGCSgEDLqJwgQQ9iyh/FgUBF4MCBYR?= =?us-ascii?q?3ChkoDWIDgTQCAQYSfCqMaBqBQT+BR4IsLj6CGoFpOoMWgmAEjn8ZjG6YLU1Ng?= =?us-ascii?q?hmBCwuNXoVghG4ggnOJLYUhjVWeRpF9DyOBR4F4MxojUDGCOFAZDY4eGoNXgVi?= =?us-ascii?q?JGigwGh0CBggBAQMJkCUBAQ?= X-IPAS-Result: =?us-ascii?q?A0AXAgBke/tehjHSVdFgHAEBAQEBAQcBARIBAQQEAQFAgUq?= =?us-ascii?q?CVEVUMxcVhDGDeo0bmhyBaAsBAwEMGw4GBAEBhEcCgiwCHAcBBDQTAhABAQUBA?= =?us-ascii?q?QECAQMDBAETAQEBCAsLCCmFYgyCNymDDwEBBBIRBBkBGxILAQMMBgULDQICJgI?= =?us-ascii?q?CIQEBEQEFARwGEyKDBAGCSgEDLqJwgQQ9iyh/FgUBF4MCBYR3ChkoDWIDgTQCA?= =?us-ascii?q?QYSfCqMaBqBQT+BR4IsLj6CGoFpOoMWgmAEjn8ZjG6YLU1NghmBCwuNXoVghG4?= =?us-ascii?q?ggnOJLYUhjVWeRpF9DyOBR4F4MxojUDGCOFAZDY4eGoNXgViJGigwGh0CBggBA?= =?us-ascii?q?QMJkCUBAQ?= X-IronPort-AV: E=Sophos;i="5.75,298,1589234400"; d="scan'208";a="353189133" X-MGA-submission: =?us-ascii?q?MDEjU0b3nRbvRtS2riFT5jqMILG0eL6HhJUAbC?= =?us-ascii?q?vI6G+2DiPuTSMBeA9P7MhXlyH9RDq/RABUVAcKpdi6kcX7s5h8MZBRzX?= =?us-ascii?q?ozvMuINTpHcovB2LjJ6UbkdYZt445t1Jlt+Z5/zaSc1Me4XAtUfKKDbn?= =?us-ascii?q?eZ1Lq4oaXycBFgtqq5u+Wfwg=3D=3D?= Received: from mail-ot1-f49.google.com ([209.85.210.49]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/AES256-GCM-SHA384; 30 Jun 2020 19:55:10 +0200 Received: by mail-ot1-f49.google.com with SMTP id 18so19108644otv.6 for ; Tue, 30 Jun 2020 10:55:10 -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 :cc:content-transfer-encoding; bh=NUSFdrpt4ucylMV1SZD55aIyyn2t1bI3UqqBk+j4qLo=; b=F/yXVuRqY7rlYpyruFKrdbvTtggfdTwEu8iCyfQ+xV+rck4lZ+9+FaigXbtJUp75bA e5wsNSgsPn8hyFcYU6zTsbDBnRIG6myvihJ06JfUqVsV9kSyydhx1uEUuKeSX98naMIA JFRbeLyrDCFePXFojGe861ish6k3D2RmcsOEZ2pgnyhCmC0x9g3I6YnPpKrLlzsp65b7 cN7amVRtAoPp40h/6+5ANPodWCaoe88wIswYlH29TEdJ2E2v6IOsKevNfh9ph+mkUFBu 6F1JvMpOLjH94nnLWBbnIxkxUxMsLbcDD4AKrWldT2+Mx2305UlpCuH4qRC6lYi/Ve08 OX8A== 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:cc:content-transfer-encoding; bh=NUSFdrpt4ucylMV1SZD55aIyyn2t1bI3UqqBk+j4qLo=; b=Uhq73y0tv+ArZFEoEsy3WtXuSca0ycyp+UlzuAEeHfPPgFsaUB8GGgrwIxDp502uSg 6PnHnkIVQMN3O41pSk9xQ/JZlIZhb6MoDiXkpvTMuqFNVNSE9aex94FDEFK0AlohBLGV S8jPsn8WkTkEF6LNcQnKDL6IPDQy/PR9sFfwWGMzx3xbsWykq1oJLZPNG9bKHdjN6YSe Crh19E2pmOFVRkkthyPc89MeL6TSSj7XOukhArfhEyJFZaUv+utr/BEFEMMNvxDehixN V3YWpkYUtzITtbMcwXvGa6uVcAeQaT0Eme/TRa27zY4qn3ZvOkhrLsg1eGCYGxS/8trQ /I0Q== X-Gm-Message-State: AOAM533UoqGeKrA1e+i2TXuJQC6XKKuHfyJWcWAYkKfS4GeyVCtpwK7K lQSvHmVRsikjS8RLtDV+DdAaJzYRkIp3EhzKUFCjySsz X-Google-Smtp-Source: ABdhPJzSX0NKAO+uURuwUZJiVjFaMHsA3FL8V9s5r9w+/ySccYQTwt5BXUCxXtrOdPzVaHSDe5bWrBKWISrUYaVUKvE= X-Received: by 2002:a9d:6047:: with SMTP id v7mr2413234otj.161.1593539709551; Tue, 30 Jun 2020 10:55:09 -0700 (PDT) MIME-Version: 1.0 References: <20200630162539.itp2j2xpdgyvaeif@posteo.net> In-Reply-To: From: Yotam Barnoy Date: Tue, 30 Jun 2020 13:54:58 -0400 Message-ID: To: Yawar Amin Cc: Sam Kuper , "ML caml-list (ocaml discuss)" Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Subject: Re: [Caml-list] Restrict type to specific chars Reply-To: Yotam Barnoy X-Loop: caml-list@inria.fr X-Sequence: 18187 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: A simpler option is to just encode chars as variants: type t =3D A | B | C and then have conversion functions let t_of_char =3D function | 'a' -> A | 'b' -> B | 'c' -> C | _ -> invalid_arg "Unsupported char" let char_of_t =3D function | A -> 'a' | B -> 'b' | C -> 'c' On Tue, Jun 30, 2020 at 1:34 PM Yawar Amin wrote: > > 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' =3D a > > ...or other similar things where values would be types. > > What you would usually do is make an abstract (or private) type that allo= ws constructing only valid values. E.g., > > module Ab : sig > type t =3D private char > val make : char -> t option > end =3D struct > type t =3D char > let make char =3D match char with 'a' | 'b' -> Some char | _ -> Non= e > end > > This allows constructing only values containing 'a' or 'b', with the guar= antee 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)` (bas= ically, upcasting). > > Regards, > > Yawar > > On Tue, Jun 30, 2020 at 12:26 PM Sam Kuper wro= te: >> >> 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 =3D Ab of char 'a' | Ab of char 'b' ;; >> type ab =3D Ab of char 'a' | Ab of char 'b' >> >> and thereby give the following functionality: >> >> # Ab 'a';; >> - : ab =3D Ab 'a' >> # Ab 'b';; >> - : ab =3D 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 =3D 'a' | 'b';; >> Error: Syntax error >> >> # type ab =3D char 'a' | char 'b';; >> Error: Syntax error >> >> # type ab =3D Ab of char 'a' | Ab of char 'b';; >> Error: Syntax error >> >> # type 'a ab =3D 'a constraint 'a =3D 'a' | 'b';; >> Error: Syntax error >> >> # type 'a ab =3D 'a constraint 'a =3D 'a' | 'a =3D '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.