Tipi tipi di firma per elenchi, ecc.
-
28-10-2019 - |
Domanda
Come definiresti le seguenti firme di tipo in inglese semplice:
Ord a => ...
Eq a => ...
Num a => ...
Potresti descrivere il significato di questi e farmi sapere quali sono le differenze (in termini di come lo spiegherei a qualcun altro)?
Grazie.
Soluzione
Questi sono tutti esempi di "vincoli di classe": limitano quali tipi possono essere utilizzati al posto della variabile di tipo che li segue (a
in questo caso), richiedendo che appartenga a un particolare Digita classe. Ord
, Eq
e Num
sono esempi di classi di tipo.
Ord a => ...
significaa
è un tipo che ha una nozione naturale di ordine ad esso associata. Ad esempio, i numeri interi possono essere organizzati naturalmente da più piccoli a più grandi. In termini matematici, esiste a Ordine totale Sua
. Un esempio ovvio una funzione che richiede questo vincolo èsort :: Ord a => [a] -> [a]
; Leggi questa firma come dirlosort
Funziona solo su elenchi di cose che possono essere messe in ordine l'una rispetto all'altra.Eq a => ...
significaa
è un tipo i cui membri possono essere paragonati tra loro per una nozione di uguaglianza. In termini matematici, esiste un relazione di equivalenza Sua
. Si noti che questa è una superclasse diOrd
, che significa qualsiasi cosa che abbia una nozione di ordinazione deve anche avere una nozione di equivalenza. Un esempio di una funzione che richiede questo vincolo èelem :: Eq a => a -> [a] -> Bool
(che determina se un elenco contiene un determinato elemento); Leggi questa firma come dirloelem
Funziona solo su elenchi di cose che possono essere paragonate tra loro per l'uguaglianza. Se pensi a come scriverestielem
te stesso, dovrebbe avere senso.Num a => ...
significaa
è un tipo numerico, il che significa che supporta alcune operazioni aritmetiche di base:+
,*
,-
,abs
. Credo che questo sia approssimativamente simile alla nozione matematica di a squillo. Fondamentalmente tutti i tipi che ritieni come "tipi di numeri" appartengono a questa classe:Int
,Double
, ecc. Vedresti ilNum a =>
Vincolo di fronte a una firma se la funzione è stata scritta per funzionare genericamente con qualsiasi tipo di numero. Per esempio,sum :: Num a => [a] -> a
, che riassume tutti gli elementi di un elenco di numeri, può funzionare ugualmente bene su[Int]
,[Double]
,[Rational]
, ecc ... tutto ciò che deve fare è sommare il suo contenuto, indipendentemente dal tipo di numeri. Ma i numeri devono essere!
Fondamentalmente, queste classi/vincoli di tipo sono un approccio al "sovraccarico di principio" delle funzioni. Possiamo usare (==) :: Eq a => a -> a -> Bool
su vari tipi, ma non solo alcun tipo. Alcune cose, ad esempio funzioni, non hanno senso confrontarsi per l'uguaglianza (forse perché l'uguaglianza non è decidibile per quel tipo) e esso mai ha senso confrontare due cose di diverso Tipi per l'uguaglianza (contrastalo con Java, in cui è possibile confrontare due oggetti di tipi possibilmente diversi per l'uguaglianza).
Per ulteriori letture (molto accessibili) su classi e vincoli di tipo, consiglio vivamente Impara un Haskell.