Tiramitsu
Tiramitsu

Reputation: 71

Ocaml : using records and variants in argument types

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

Answers (1)

Pierre G.
Pierre G.

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

Related Questions