OCaml functors :: comportamiento contraintuitivo

Estoy experimentando con el lenguaje de módulos de OCaml (3.12.1), definiendo functores y firmas para módulos, etc., principalmente siguiendo los ejemplos deCapítulo 2 del manual de OCaml y me he topado, por accidente, con una situación en la que aparentemente mi modelo mental de cómo funcionan las firmas de los functors y los módulos es defectuoso. Traté de reducir la situación que encontré a la menor cantidad de código posible, así que no pregunte qué estoy tratando de lograr, este es un ejemplo totalmente inventado para demostrar la función OCaml en cuestión.

Entonces, tenemos un functor que simplemente proporciona una función de identidad 'f' y está parametrizado por un módulo que proporciona el tipo de parámetro de entrada de esa función. Ejemplo totalmente artificial como dije.

module type SOMETYPE = sig type t end ;;
module Identity = functor (Type: SOMETYPE) -> struct let f (x: Type.t) = x end ;;

Dado lo anterior, procedemos a definir un módulo para suministrar el tipo int:

module IntType = struct type t = int end ;;

.. y luego usamos el functor para generar un módulo para la función de identidad int:

module IdentityInt = Identity(IntType) ;;                     

Asegúrese de que el módulo generado y su función f se comporten como se esperaba:

#IdentityInt.f(3) + 10 ;;
- : int = 13

El modelo mental de los functores como funciones que toman módulos como entradas y módulos de retorno parece estar sirviéndonos bien hasta ahora. LosIdentity functor espera como parámetro de entrada un módulo de firma (tipo de módulo) SOMETYPE, y de hecho el módulo que suministramos IntType) tiene la firma correcta y, por lo tanto, se genera un módulo de salida válido IdentityInt) cuyofa función @ se comporta como se esperaba.

Ahora viene la parte no intuitiva. ¿Qué pasaría si quisiéramos hacer explícito que el módulo suministradoIntType es de hecho un tipo de módulo SOMETYPE. Como en

module IntType : SOMETYPE = struct type t = int end ;;

y luego generar el módulo de salida del functor de la misma manera que antes:

module IdentityInt = Identity(IntType) ;;

... intentemos usar laf función del módulo recién generado:

IdentityInt.f 0 ;;

Con lo cual el REPL se queja con:

"Error: This expression [the value 0] has type int but an expression was expected of type IntType.t."

¿Cómo puede proporcionar información de tipo redundante pero correcta romper el código? Incluso en el caso A, el módulo de función Identity tuvo que tratar laIntType módulo comoSOMETYPE tipo. Entonces, ¿cómo es que se declara explícitamenteIntType ser - estarSOMETYPE type produce un resultado diferente?

Respuestas a la pregunta(8)

Su respuesta a la pregunta