类型表达式中的 as 是什么?

问题描述 投票:0回答:2

Ocaml 5 手册第 11.4 节说 typeexpr 的形式可以是

typexpr as ' ident
.

这些

as
别名是做什么用的?

这里有一些编译的例子:

type 'a x = 'a as int

type y = 'a as int`

起初我以为

as
别名就像类型级别的
let
s,但我无法弄清楚如何使用新类型变量,或者这与
constraint
有何不同:

type x = 'a as int in ('a, 'a) (* doesn't compile *)
types ocaml type-alias
2个回答
3
投票

首先,您的示例无法编译:

# type 'a x = 'a as int;;
Error: Syntax error
# type y = 'a as int`;;
Error: Syntax error

as
的目的是给定义的类型的某些部分起一个名字,这样这个名字就可以在同一类型定义的其他地方使用。这允许类型具有递归子结构。我相信这在处理带有
-rectypes
标志的奇异类型时很有用。

这里是一个递归类型的例子,它由一个列表组成,其元素是相同类型的列表。据我所知,这种类型的唯一值是......空列表列表的列表。

$ rlwrap ocaml -rectypes
OCaml version 4.14.0
Enter #help;; for help.

# type abc = 'a list as 'a;;
type abc = 'a list as 'a
# ([] : abc);;
- : abc = []
# ([[]] : abc);;
- : abc = [[]]
# ([[[]]] : abc);;
- : abc = [[[]]]
# ([[]; []] : abc);;
- : abc = [[]; []]
# ([[]; [[]]] : abc);;
- : abc = [[]; [[]]]
# 

2
投票

类型级别的别名(

_ as _
)有三个相对不同的用例:

  • 地方简称:
val triple_printer: (Format.formatter -> 'a -> unit as 'pr) -> 'pr -> 'pr -> (Format.formatter -> ('a * 'a * 'a) -> unit

在这里

_ as 'pr
避免在不求助于显式类型定义的情况下为单个元素重复复杂类型打印机类型。

  • 递归类型:特别是,递归类型很自然地出现在多态变体和对象中。 例如
type 'a tree = [ `Leaf of 'a | `Node of 'tree list ] as 'tree
let x :  let x : _ tree = `Node [`Leaf 1; `Node [`Leaf 2; `Leaf 3]]
class c x = object val x = x method incr = {< x = x + 1 >} end
let incr (c: < incr: 'self; .. > as 'self) = c#incr
let test = incr (new c 0)

请注意,在多态变体和对象之外,需要使用

rectypes
选项显式启用等递归类型。

  • 一种限制形式的约束,在定义具有开放行类型变量的类型族时最有用:
type 'a t = <x:int; y :int; .. > as 'a

相当于

type 'a t = 'a
  constraint 'a = <x:int; y:int; .. >

and 是必需的,因为

..
隐藏了一个必须在定义中绑定的隐式类型变量。 然而,在这种情况下定义更接近的形式通常更简单

type t = < x : int; y : int >

并在需要开放变体时使用定义内联:

let f (c: < t; .. >) = c#x + c#y 

此外,显式在复杂情况下更通用。例如,我可以总结

的类型
let f x = x#step_1#step_2#step_3

通过定义一系列约束

type 'a t = 'r
  constraint 'a = <step_1:'s1; .. >
  constraint 's1 = <step_2:'s2; ..>
  constraint 'r = <step_3:'r; ..>
© www.soinside.com 2019 - 2024. All rights reserved.