OCaml中的显式var类型

Ram*_*esh 2 ocaml

如果我有一个类型t

type t = C of string;;

并且想要明确定义变量的类型为t:

let b : t = C 'MyString';;

我可以在OCaml中做到吗?

gas*_*che 11

你并不需要是明确的

let b = C mystring
let b = C "a string litteral"
Run Code Online (Sandbox Code Playgroud)

可以是明确的,但它没有添加任何东西

let b : t = C foo
Run Code Online (Sandbox Code Playgroud)

一般来说,首选方法是在没有注释类型的情况下使用类型推断,并且只通过关联的.mli接口文件明确表示导出到其他模块的标识符的类型.

在这种情况下,类型注释不会添加任何内容,因为C构造函数已经是一种标记/注释:C something必然是类型t,不存在混淆.


Vic*_*let 5

您可以使用该语法或备用语法:

let b = (C foo : t)
Run Code Online (Sandbox Code Playgroud)

以这种方式添加类型约束通常不会在格式良好的程序中用于任何目的,因为类型推断算法可以自己正确地处理所有这些.有一些例外(主要涉及面向对象的方面),但它们非常罕见.

这种注释在发生类型错误时非常有用,并且当您希望某个表达式具有另一种类型时,您需要理解某个表达式具有某种类型的原因,因为您可以键入 - 注释中间值以使类型错误通过源代码向上移动.

请注意,还有另一种注释类型的方法,即为模块定义签名.在上面的示例中,您的模块主体将包含:

let b = C foo 
Run Code Online (Sandbox Code Playgroud)

您的模块签名将包含:

val b : t
Run Code Online (Sandbox Code Playgroud)

当您需要模块内部的假设对其他模块不可见时,这尤其有用.例如,使用多态变体时:

let user_type = `Admin
Run Code Online (Sandbox Code Playgroud)

在这里,您只想处理管理员帐户,但是您需要让其余的代码知道存在其他帐户类型,因此您需要在签名中写下:

val user_type : [`Admin|`Member|`Guest]
Run Code Online (Sandbox Code Playgroud)

这种类型在技术上是正确的,但是类型推断算法无法猜到.