* [Caml-list] Restrict type to specific chars
@ 2020-06-30 16:25 Sam Kuper
2020-06-30 17:33 ` Yawar Amin
2020-06-30 18:07 ` Jesse Haber-Kucharsky
0 siblings, 2 replies; 4+ messages in thread
From: Sam Kuper @ 2020-06-30 16:25 UTC (permalink / raw)
To: ML caml-list (ocaml discuss)
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: <some 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.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Caml-list] Restrict type to specific chars
2020-06-30 16:25 [Caml-list] Restrict type to specific chars Sam Kuper
@ 2020-06-30 17:33 ` Yawar Amin
2020-06-30 17:54 ` Yotam Barnoy
2020-06-30 18:07 ` Jesse Haber-Kucharsky
1 sibling, 1 reply; 4+ messages in thread
From: Yawar Amin @ 2020-06-30 17:33 UTC (permalink / raw)
To: Sam Kuper, ML caml-list (ocaml discuss)
[-- Attachment #1: Type: text/plain, Size: 2741 bytes --]
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 <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'. 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: <some 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.
>
[-- Attachment #2: Type: text/html, Size: 3941 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Caml-list] Restrict type to specific chars
2020-06-30 17:33 ` Yawar Amin
@ 2020-06-30 17:54 ` Yotam Barnoy
0 siblings, 0 replies; 4+ messages in thread
From: Yotam Barnoy @ 2020-06-30 17:54 UTC (permalink / raw)
To: Yawar Amin; +Cc: Sam Kuper, ML caml-list (ocaml discuss)
A simpler option is to just encode chars as variants:
type t = A | B | C
and then have conversion functions
let t_of_char = function
| 'a' -> A
| 'b' -> B
| 'c' -> C
| _ -> invalid_arg "Unsupported char"
let char_of_t = function
| A -> 'a'
| B -> 'b'
| C -> 'c'
On Tue, Jun 30, 2020 at 1:34 PM Yawar Amin <yawar.amin@gmail.com> 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' = 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 <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'. 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: <some 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.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Caml-list] Restrict type to specific chars
2020-06-30 16:25 [Caml-list] Restrict type to specific chars Sam Kuper
2020-06-30 17:33 ` Yawar Amin
@ 2020-06-30 18:07 ` Jesse Haber-Kucharsky
1 sibling, 0 replies; 4+ messages in thread
From: Jesse Haber-Kucharsky @ 2020-06-30 18:07 UTC (permalink / raw)
To: Sam Kuper, ML caml-list (ocaml discuss)
[-- Attachment #1: Type: text/plain, Size: 2480 bytes --]
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'. 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: <some 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
[-- Attachment #2: Type: text/html, Size: 3625 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2020-06-30 18:07 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-30 16:25 [Caml-list] Restrict type to specific chars Sam Kuper
2020-06-30 17:33 ` Yawar Amin
2020-06-30 17:54 ` Yotam Barnoy
2020-06-30 18:07 ` Jesse Haber-Kucharsky
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox