2012-07-31 17 views
5

Encontré algo que realmente no entiendo al trabajar en un proyecto ocaml.programación modular en ocaml

Supongamos que estoy utilizando los módulos Array y List de la biblioteca estándar OCaml. Ambos implementan la función length pero tienen diferentes tipos. En el módulo List, este es su tipo:

length: a' list -> int 

Y en el módulo Array, tiene el tipo:

length: a' array -> int 

Pero entonces yo quería utiliza los dos módulos en el mismo módulo que estaba implementar, a través de la open palabra clave:

open List 
open Array 

Cuando traté de usar la función length en una lista, tuve un error de tipo durante la compilación.
Dado que OCaml es un lenguaje fuertemente tipado estáticamente, me pregunto por qué el compilador no sabía que quería la función de longitud del módulo de lista ya que declaraba que estaba usando ambos.

+1

"Me pregunto por qué el compilador no sabía que quería la función de longitud del módulo de lista ya que declaré que estaba utilizando tanto" Sí, pero ¿cuál sería el tipo de 'diversión s -> longitud s' en este contexto entonces? –

+0

Según la respuesta de jrouquie, será 'a 'array -> int' –

+1

Exactamente, pero en el caso de un compilador OCaml hipotético que intentó adivinar, no habría ningún tipo más general en el sistema de tipo OCaml para la función. Puede que le interese la solución de Haskell a esta molestia, escriba las clases: http://www.haskell.org/tutorial/classes.html –

Respuesta

8

OCaml no elige una función u otra en función de sus tipos.

Cuando se escribe

open Array 

las funciones del módulo de Array están enmascarando las del módulo de List con el mismo nombre. Cuando más tarde llama a la función length, OCaml busca una función llamada length, encuentra Array.length, y se queja de que esta función no tiene un tipo compatible.

La forma habitual es llamar al List.length (en lugar de solo length) si esa es la función que necesita.


Más generaly, OCaml no tiene nombre de sobrecarga (es decir, que tiene dos funciones u operadores con el mismo nombre pero distintos tipos de argumentos), en particular porque esto haría que la inferencia de tipos mucho más difícil.

+2

Además: intente evitar la apertura de módulos: hace que leer el código sea mucho más difícil porque un lector debe recordar qué módulos están abiertos (y en qué orden); también como lector, no se da cuenta de inmediato de dónde viene una función (de qué módulo de edición abierta es). – lambdapower

+2

Me gustaría agregar que los módulos de apertura están bien si el origen de los valores/funciones utilizados permanece claro. Por lo tanto, no abra módulos como List o Array que proporcionan funciones con nombres genéricos, pero "abrir Printf" está perfectamente bien porque proporciona funciones printf, fprintf, etc. cuyo origen es obvio. –