2012-05-08 14 views
5

So che OCaml non supporta il sovraccarico. Quindi, invece di sovraccaricare, cosa possiamo fare per risolvere questo problema?Sovraccarico in Ocaml

1) utilizzare invece il polimorfismo? 2) dare diverse funzioni nomi diversi? 3) metti le funzioni con lo stesso nome in diversi moduli?

Quale funzionerà?

risposta

13

Tutto dipende da cosa intendi sovraccaricare. Esistono diversi casi d'uso, come ad esempio:

Se si desidera utilizzare il solito nome di operatori infisso in un'espressione matematica che manipola qualcos'altro rispetto agli interi: rebind localmente gli operatori; moduli e "locale aperto" possono aiutare con quello.

module I32 = struct 
    open Int32 
    let (+), (-), (*), (/), (!!) = add, sub, mul, div, of_int 
end 

... I32.(x + y * !!2) ... 

Se si desidera un operazione da polimorfa nel tipo di tipo numerico in uso, è necessario astratto su tali operatori numerici. Ad esempio, la funzione di elevazione a potenza veloce generico (da un intero), che può essere utilizzato su matrici ecc

let rec pow (*) one a = function 
    | 0 -> one 
    | n -> pow (*) (if n mod 2 = 0 then one else one * a) (a * a) (n/2) 

let() = assert (pow (*.) 1. 2. 3 = 8.) 

Più in generale, sì, l'idea è quella di catturare ciò che si vuole "sovraccarico" come un insieme di operatori (qui gli operatori infissi, ma i nomi semplici sono buoni e spesso migliori per la leggibilità), e passano in rassegna e astratti i dizionari di quelle operazioni - proprio come le classi di tipi Haskell sono compilate, in effetti.

+0

Noto che hai fatto un 'Int32 aperto' nel modulo I32, cosa sarebbe diverso se tu avessi fatto un 'include Int32' lì invece? Sono essenzialmente equivalenti in quel contesto? – aneccodeal

+1

@aneccodeal: sarebbe molto diverso: se usassi 'include', questo' I32' includerebbe tutto 'Int32', quindi aprire 'I32' localmente importerebbe in particolare tutte le definizioni di' Int32'. Preferisco non aprire grandi scope perché rischia di oscurare le definizioni degli utenti. – gasche