Why does this work fine?
module Account = struct
type account_type = Current of float | Savings of float
end
let sarah = Account.Current 100.0;;
While the final line in the following produces an Error: syntax error
?
module Account = struct
type 'a account_type = [> `Current of float | `Savings of float ] as 'a
end
let pete = Account.`Current 100.0;;
That is, why can't I use the open union type outside the module without opening the module? I should say I've found out that changing the final line to:
open Account;;
let pete = `Current 100.0;;
works fine, but obviously this is cumbersome if I use account_type
a lot, or alternatively I have to open Account
at the start of any code section where account_type
is used, which means I'd sacrifice the abstraction I'd get by using a signature for Account
I've trawled through several OCaml tutorials as well as the INRIA documentation, and I can't find any mention of how you do this.
Is it possible to avoid having to open the module every time I want to use an account_type
?
Thanks in advance,
Zach
In the second example, you actually don't have to open Account
at all, the syntax is just `Current 100.0
. A Polymorphic variant tag does not participate in any particular type. The type of `Current
is [> `Current ]
, this (the >
) means the type is at least `Current
, and since that is a subset of the type accepted by the function, it will compile just fine. You can pass that same value to a number of functions that accept a polymorphic variant of the same name. Of course, there is a lack of static type information, and typing errors and situations can become quite complex.
Code Reuse through polymorphic variants talks about some advantages and use cases for them.
The polymorphic variant constants like `Current
are globally defined, similarly to integer constants. You wouldn't say Account.10
to reference the integer 10 inside the Account
module.
This is the strength (and weakness) of polymorphic variants, you can use them without defining them (like you don't have to define 10 before using it).
So, as nlucaroni says, you don't have to open the Account
module to get access to `Current
.
Unlike the integers, polymorphic variants can also take parameters (as in your `Current 100.0
). But the number of parameters and their types aren't fixed, and they can even vary for the same constructor in different places in the code. Hence the complexities also mentioned by nlucaroni.
[Formatting note: to get single backquotes `
to show up in typewriter-styled text, the markdown convention is to use doubled backquotes to enclose the text. This leaves single backquotes alone inside the text. Or at least it's working for me.]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With