Estás viendo esto mal (aunque no te culpo: es bastante sorprendente al principio). Puede parecerle que los constructores siguen la sintaxis Name of type
, donde la parte de tipo sigue la sintaxis de tipo normal (que le permite contener tuplas).
En realidad, tuplas y constructores siguen la misma sintaxis exacta: un constructor no es más que una tupla con un nombre delante de él:
tuple/constructor == [name of] type [* type] [* type] ...
Así, el *
en una definición de constructor no son parte de la sintaxis de tupla, son parte de la sintaxis del constructor. Está literalmente definiendo un constructor como este nombre, seguido de N argumentos en oposición a este nombre, seguido de un argumento que es una tupla.
La razón detrás de esta sutil diferencia en el comportamiento es la de rendimiento. En este momento, tuplas y constructores están representados en la memoria como tal:
[TYPE] [POINTER] [POINTER] [POINTER]
Esta es una representación bastante compacto y eficiente.Si se pudieran acceder a los múltiples argumentos de un constructor como una tupla, esto requeriría que el tiempo de ejecución represente esa tupla independientemente del constructor (para que sea direccionable independientemente) y así sería:
[TYPE] [POINTER]
|
v
[TYPE] [POINTER] [POINTER] [POINTER]
Esto usaría marginalmente más memoria, requeriría el doble de asignaciones cuando se usa un constructor, y reduciría el rendimiento de las tuplas de coincidencia de patrones (debido a una desreferencia adicional). Para conservar el máximo rendimiento, el name of type * type
se representa con el primer patrón, y debe escribir explícitamente name of (type * type)
para cortar el *
del of
y volver al segundo patrón.
Tenga en cuenta que se accede a ambos patrones a través de la misma sintaxis de coincidencia de patrones y construcción: name (arg,arg)
. Esto significa que la inferencia de tipo no puede deducir el patrón en función del uso. Esto no es un problema para los constructores normales, que siempre se definen en una definición de tipo, pero causa variantes (que no necesitan una definición preliminar) para volver automáticamente a la segunda versión.
Lectura adicional sobre la representación de memoria de los tipos here.
¡Guau! Gracias por la larga explicación! Su comprensión de OCaml hace que parezca que usted es de INRIA – axsuul