在元组解包中键入声明

时间:2012-03-15 21:30:41

标签: ocaml

给出一个类型:

type coords = int * int 

以下作品:

# let c : coords = 3, 4;;
val c : coords = (3, 4)

我也希望能够做到:

# let (x, y) : coords = 3, 4;;
  let (x, y) : coords = 3, 4;;
Error: Syntax error

但它抱怨:上的语法错误。这在语法上是否可行?

2 个答案:

答案 0 :(得分:8)

语法let x : t = …是更一般语法

的无参数情况
let f a1 … an : t = …

其中t是函数f的返回类型。标识符f必须只是一个标识符,你不能在那里有一个模式。你也可以写一些像

这样的东西
let (x, y) = …

此处(x, y)是一种模式。类型注释可以出现在模式中,但必须用括号括起来(如表达式中所示),因此需要编写

let ((x, y) : coords) = …

请注意,除了一些化妆品报告消息之外,此注释是无用的; xy仍然具有int类型,而(x, y)仍然具有int * int类型。如果您不希望坐标与整数的类型相同,则需要引入构造函数:

type coords = Coords of int * int
let xy = Coords (3, 4)

如果这样做,单个坐标仍然是整数,但是一对坐标是具有自己类型的构造对象。要获得一个坐标的值,构造函数必须包含在模式匹配中:

let longitude (c : coords) = match c with Coords (x, y) -> x

答案 1 :(得分:1)

语法

let x : t = ...

意味着您在大多数情况下不必要地告诉编译器名称 x 的类型是 t < / strong>(或者您可能只是想为了可读性目的而添加此类型信息)。在您的示例中:

let (x,y) : coords =

你必须问自己:类型是 coords 的名称是什么?显然,您没有定义这样的名称, x 的类型是 int y 的类型也是如此。左侧没有类型 coords 的名称。如果您已经有coords值,可以将其拆分如下:

# type coords = int*int ;;
type coords = int * int
# let c:coords = 3,4 ;;
val c : coords = (3, 4)
# let x,y = c;;
val x : int = 3
val y : int = 4

在上面的例子中

let  c: coords = 3,4 ;;

您实际上是让编译器为名称c分配一个coords类型(否则int * int将被用作类型)。