我正在尝试使用OCaml的模块语言(3.12.1),为模块定义仿函数和签名等等,主要是遵循OCaml手册第2章中的示例,我偶然发现了一个明显的情况我的仿函数和模块签名如何工作的心理模型是有缺陷的.我试图将我遇到的情况缩小到可能的最短代码量,所以不要问我想要完成什么,这是一个完全人为的例子来演示有问题的OCaml功能.
因此,我们有一个functor,它只提供一个标识函数'f',并由一个提供该函数输入参数类型的模块进行参数化.像我说的完全做作的例子.
module type SOMETYPE = sig type t end ;;
module Identity = functor (Type: SOMETYPE) -> struct let f (x: Type.t) = x end ;;
Run Code Online (Sandbox Code Playgroud)
鉴于上述情况,我们继续定义一个模块来提供int类型:
module IntType = struct type t = int end ;;
Run Code Online (Sandbox Code Playgroud)
..然后我们使用函子为int标识函数生成一个模块:
module IdentityInt = Identity(IntType) ;;
Run Code Online (Sandbox Code Playgroud)
确实生成的模块及其f函数的行为符合预期:
#IdentityInt.f(3) + 10 ;;
- : int = 13
Run Code Online (Sandbox Code Playgroud)
函数的心理模型是将模块作为输入和返回模块的函数,这似乎是为我们提供了正确的服务.该Identity函子预计作为输入参数签名(模块型)的模块SOMETYPE,而事实上,我们提供的模块(IntType)具有正确的签名,因此一个有效的输出模块产生(IdentityInt),其f功能行为与预期.
现在是不直观的部分.如果我们想明确提供的模块IntType确实是SOMETYPE类型的模块,该怎么办?如:
module IntType : SOMETYPE = struct type t = int end ;; …Run Code Online (Sandbox Code Playgroud)