Ocaml:在参数类型中使用记录和变体

Posted

技术标签:

【中文标题】Ocaml:在参数类型中使用记录和变体【英文标题】:Ocaml : using records and variants in argument types 【发布时间】:2018-05-06 06:53:58 【问题描述】:

作为 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 |飞行。

也许这种把戏是有可能的?

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

【问题讨论】:

我认为你已经在你的函数中添加了模式匹配,我猜 OCaml 设计师更关心开发更快更实用的编译器,而不是最聪明的编译器。但可能是一些严格类型编程的教条(是 Str 和 Flt 类型的 monad 或 smth) 可能是关于显式多态性注释的章节,可以为您澄清吗? caml.inria.fr/pub/docs/manual-ocaml/polymorphism.html 谢谢 Serge,我会检查一下! 【参考方案1】:

在表达式 let get_bar_3 (comp : string_or_float_component) 中,comp 是枚举类型:Str of somethingFlo 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;;

【讨论】:

谢谢!我想知道,因为一个变体可以包含所有东西,它不能保证它的所有构造函数都共享相同的结构。 caml.inria.fr/pub/docs/manual-ocaml-400/manual006.html 4.2 节暴露了我遇到的问题。让我们看看这个魔法是如何运作的!

以上是关于Ocaml:在参数类型中使用记录和变体的主要内容,如果未能解决你的问题,请参考以下文章

Ocaml 值与模块和签名中的参数化类型不匹配

内联记录是否包含多态变体?

OCaml 类型推断不会产生函数参数的预期类型

在 Mongoose 中定义变体类型

OCaml 表达式类型问题

多态变体和构造函数