给出一个类型:
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
但它抱怨:
上的语法错误。这在语法上是否可行?
答案 0 :(得分:8)
语法let x : t = …
是更一般语法
let f a1 … an : t = …
其中t
是函数f
的返回类型。标识符f
必须只是一个标识符,你不能在那里有一个模式。你也可以写一些像
let (x, y) = …
此处(x, y)
是一种模式。类型注释可以出现在模式中,但必须用括号括起来(如表达式中所示),因此需要编写
let ((x, y) : coords) = …
请注意,除了一些化妆品报告消息之外,此注释是无用的; x
和y
仍然具有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将被用作类型)。