如果我有类型t
type t = C of string;;
并希望明确定义变量类型为t:
let b : t = C 'MyString';;
我可以在OCaml中完成吗?
答案 0 :(得分:11)
你 需要明确
let b = C mystring
let b = C "a string litteral"
你可以明确,但它没有添加任何东西
let b : t = C foo
一般来说,首选方法是在没有注释类型的情况下使用类型推断,并且只能通过关联的.mli
接口文件明确表示导出到其他模块的标识符的类型。
在这种情况下,类型注释不会添加任何内容,因为C
构造函数已经是一种标记/注释:C something
必须是t
类型,没有可能有困惑。
答案 1 :(得分:5)
您可以使用该语法或替代语法:
let b = (C foo : t)
以这种方式添加类型约束通常不会在格式良好的程序中用于任何目的,因为类型推断算法可以自己正确地处理所有这些。有一些例外(主要涉及面向对象的方面),但它们非常罕见。
这种注释在发生类型错误时非常有用,并且您需要了解某个表达式在您希望它具有另一个时具有某种类型的原因,因为您可以键入 - 注释中间值以使类型错误向上移动你的源代码。
请注意,还有另一种注释类型的方法,即为模块定义签名。在上面的示例中,您的模块主体将包含:
let b = C foo
您的模块签名将包含:
val b : t
当您需要模块内部的假设对其他模块不可见时,这尤其有用。例如,使用多态变体时:
let user_type = `Admin
在这里,您只想处理管理员帐户,但是您需要让其余代码知道存在其他帐户类型,因此您需要在签名中写下:
val user_type : [`Admin|`Member|`Guest]
这种类型在技术上是正确的,但是类型推断算法无法猜到。