Reputation: 71
As a newbie in Ocaml, I'm playing with type and try to understand how variants work.
Here is the sample :
type 'a component =
{ foo : int;
bar : 'a }
type string_or_float_component =
| Str of string component
| Flt of float component
let get_foo_1 (comp: 'a component) = comp.foo
(* works *)
let get_foo_2 (Str comp) = comp.foo
(* works *)
let get_bar_3 (comp : string_or_float_component) = comp.foo
(* This expression has type string_or_float_component
but an expression was expected of type 'a component *)
I'm not try to find the best solution (like pattern matching), just understand why ocaml can't infers in the get_bar_3 that component is Str | Flt.
Maybe that kind of trick is someway possible ?
type 'a string_or_float =
| Str of string 'a
| Flt of float 'a
Thanks
(I'm using bucklescript)
Edit :
Realised that my problem is more design related. I could work with something like this :
type string_or_float =
| Str of string
| Flt of float
type 'a component = { foo: int; bar: 'a }
let get_bar_3 (comp : string_or_float component) ...
Upvotes: 1
Views: 734
Reputation: 4431
In the expression let get_bar_3 (comp : string_or_float_component)
, comp
is an enumerated type : either a Str of something
or a Flo of something
.
In any case, comp
is not a record type at that point, only something
is a record type.
To extract the field from something
:
let get_bar_3 (comp : string_or_float_component) = let Str a = comp in a.foo;;
Which will give a warning at compile type. The complete code is rather this one :
let get_bar_3 (comp : string_or_float_component) = match comp with
| Str a -> a.foo
| Flt a -> a.foo;;
Upvotes: 3