2012-07-31 14 views
5

Ho trovato qualcosa che non capisco davvero mentre lavoro su un progetto ocaml.programmazione modulare in ocaml

Supponiamo di utilizzare entrambi i moduli Array e List della libreria standard OCaml. Entrambi implementano la funzione length ma hanno tipi diversi. Nel modulo List, questo è il suo tipo:

length: a' list -> int 

E nel modulo Array, ha il tipo:

length: a' array -> int 

Ma poi ho voluto utilizzare entrambi i moduli nello stesso modulo che ero attuazione, tramite la parola chiave open:

open List 
open Array 

Quando ho provato ad utilizzare la funzione length su una lista, ho avuto un errore di tipo durante la compilazione.
Poiché OCaml è un linguaggio fortemente tipizzato staticamente, mi chiedo perché il compilatore non sapesse che volevo la funzione di lunghezza del modulo elenco poiché ho dichiarato che stavo usando entrambi.

+1

"Mi chiedo perché il compilatore non sapeva che volevo la funzione di lunghezza del modulo elenco poiché ho dichiarato che stavo usando entrambi" Sì, ma quale sarebbe il tipo di 'divertimento s -> lunghezza s' in questo contesto allora? –

+0

In base alla risposta di jrouquie, sarà 'a 'array -> int' –

+1

Esattamente, ma nel caso di un ipotetico compilatore OCaml che tentasse di indovinare, non ci sarebbe un singolo tipo più generale nel sistema di tipo OCaml per la funzione. Potresti essere interessato alla soluzione di Haskell per questo fastidio, classi di tipi: http://www.haskell.org/tutorial/classes.html –

risposta

8

OCaml non sceglie una funzione o un'altra in base al tipo.

Quando si scrive

open Array 

le funzioni del modulo Array sono mascherando quelli del modulo List con lo stesso nome. Quando in seguito si chiama la funzione length, OCaml cerca una funzione denominata length, trova Array.length e lamenta che questa funzione non ha un tipo compatibile.

Il modo normale è chiamare List.length (anziché solo length) se questa è la funzione necessaria.


Più Generaly, OCaml non ha nome sovraccaricare (cioè avente due funzioni o operatori con lo stesso nome ma distinti tipi di argomento), in particolare perché ciò renderebbe tipo inferenza molto più difficile.

+2

Inoltre: Cerca di evitare l'apertura dei moduli: rende la lettura del codice molto più difficile perché un lettore deve ricordare quali moduli sono aperti (e in quale ordine); anche come lettore non ti rendi conto immediatamente da dove proviene una funzione (da quale modulo aperto che è). – lambdapower

+2

Vorrei aggiungere che i moduli di apertura vanno bene se l'origine dei valori/funzioni utilizzate rimane chiara. Quindi non aprire moduli come List o Array che forniscono funzioni con nomi generici, ma "open Printf" è perfettamente adatto perché fornisce funzioni printf, fprintf, ecc. La cui origine è ovvia. –