Ocaml: использование записей и вариантов в типах аргументов - PullRequest
0 голосов
/ 06 мая 2018

Будучи новичком в Ocaml, я играю с шрифтом и пытаюсь понять, как работают варианты.

Вот образец:

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 *)

Я не пытаюсь найти лучшее решение (например, сопоставление с образцом), просто понимаю, почему ocaml не может определить в get_bar_3, что компонент является Str | Flt.

Может быть, такой трюк каким-то образом возможен?

type 'a string_or_float =
  | Str of string 'a
  | Flt of float 'a

Спасибо

(я использую пряжки)

Редактировать:

Понял, что моя проблема больше связана с дизайном. Я мог бы работать с чем-то вроде этого:

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) ...

1 Ответ

0 голосов
/ 06 мая 2018

В выражении let get_bar_3 (comp : string_or_float_component), comp является перечисляемым типом: либо Str of something, либо Flo of something. В любом случае comp не является типом записи на данный момент, только something является типом записи.

Чтобы извлечь поле из something:

 let get_bar_3 (comp : string_or_float_component) = let Str a = comp in a.foo;;

Что выдаст предупреждение при типе компиляции. Полный код скорее такой:

 let get_bar_3 (comp : string_or_float_component) = match comp with
  | Str a -> a.foo
  | Flt a -> a.foo;;
...