Ocaml 通过推断类型与值的接近程度消除歧义?

标签 ocaml type-inference algebraic-data-types subtyping refinement-type

type large1 = Int of int | Bool of bool
type small1 = Int of int    
let intersect1 = Int 0

ocaml 顶层 (4.01.0) 将 intersect1 的类型推断为 small1。我想我明白为什么:small1 看起来像 large1 的子类型(或细化类型)。

但现在:

type small2 = Int of int
type large2 = Int of int | Bool of bool    
let intersect2 = Int 0

顶层现在为 intersect2 推断出 large2 类型。这使得它看起来像是被用作决胜局的,但这非常令人惊讶,并且与我使用过的其他语言不同,所以我怀疑这里有一些微妙的东西我误解了。

一个并发症:如 the question that inspired the answer that inspired this question 中所述,“较近”的类型并不能完全隐藏较远的类型。

type left = Int of int | Dem
type right = Int of int | Gop

let zell (x:left) =
  match x with
    Int v -> Int v
  | Dem -> Gop

zell 被赋予类型 left -> right

推断这些类型的具体规则是什么,以及 manual 中的什么位置? (或任何其他已发表的论文或文档)我可以阅读更多内容吗?

This question was inspired by an older answer to a question about polymorphic variants.

最佳答案

如今,OCaml 对记录字段和构造函数进行了“类型定向”消歧。

自 2012 年 9 月 12 日发布的 OCaml 4.01.0 起,它已添加到语言中。发行说明请参阅此链接以获取更多信息:

Type-based selection of record labels and constructors.

这是一篇很好的文章,描述了进行更改的思维过程:

Resolving Field Names

这是包含更多详细信息的后续内容:

Resolving Field Names 2

我找不到 OCaml 手册中提到的此功能(如您所说)。

关于Ocaml 通过推断类型与值的接近程度消除歧义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42757043/

相关文章:

ocaml - 具有自定义数据类型的 Stream.of_list

syntax - OCaml 构造函数解包

typescript - 在多个级别上推断 TypeScript 中的泛型类型参数

lambda - Kotlin lambda 和类型推断

scala - 隐式转换不适用于类型安全的构建器模式

ocaml - OCaml 中的副作用和顶级表达式

types - 确定 OCaml 表达式类型的一般方法是什么?

haskell - 在这个类型化的 lambda 演算宇宙中,您如何制定 n 元积和求和类型?

polymorphism - 在 Elm 中处理具有共享子结构的记录

scala - Scala 中 Catamorphisms 的高效实现