`Ord a =>` o `Num a =>`
-
27-10-2019 - |
Domanda
Ho le seguenti funzioni:
which (x:xs) = worker x xs
worker x [] = x
worker x (y:ys)
| x > y = worker y ys
| otherwise = worker x ys
e mi chiedo come dovrei definire i tipi firme di queste funzioni sopra which
e worker
?
Ad esempio, che di sarebbe meglio come un tipo di firma i seguenti modi per i lavoratori?
worker :: Num a => a -> [a] -> a
,
o
worker :: Ord a => a -> [a] -> a
?
Sono solo molto confuso e non si ottiene che questi tre dovrei scegliere. Apprezzerei i vostri pensieri. Grazie.
Soluzione
Se si definisce la funzione senza una firma di tipo esplicito, Haskell sarà dedurre quello più generale. Se non siete sicuri, questo è il modo più semplice per capire come verrà letta la tua definizione; allora si può copiare nel codice sorgente. Un errore comune sta scrivendo in modo non corretto una funzione e quindi ottenere un errore di tipo di confusione da qualche altra parte.
In ogni caso, è possibile ottenere informazioni sulla classe Num
digitando :i Num
in ghci, oppure leggendo la documentazione. La classe Num
dà +
, *
, -
, negate
, abs
, signum
, fromInteger
, così come ogni funzione del Eq
e Show
. Si noti che <
e >
non ci sono! Che richiedono valori di Num
e tentando di confrontarli saranno infatti produrre un errore di tipo -. Non tutti i tipi di numero può essere paragonato
Così dovrebbe essere Ord a => ...
, come Num a => ...
produrrebbe un errore di tipo se si è tentato di esso.
Altri suggerimenti
Se si pensa a cosa le funzioni fanno, vedrai che which xs
restituisce il valore minimo in xs
. Che cosa può avere un valore minimo? Un elenco di qualcosa Ord
erable!
Chiedi ghci e vedere che cosa dice. Ho appena copia-incollato il codice come è in un file e caricato in ghci. Poi ho usato :t
che è un comando speciale ghci per determinare il tipo di qualcosa.
ghci> :t which
which :: (Ord t) => [t] -> t
ghci> :t worker
worker :: (Ord a) => a -> [a] -> a
inferenza dei tipi di Haskell è abbastanza intelligente nella maggior parte dei casi; imparare a fidarsi di esso. Altre risposte sufficientemente coprono perché Ord
deve essere usato in questo caso; Volevo solo essere sicuro ghci era chiaramente menzionato come una tecnica per determinare il tipo di qualcosa.
vorrei sempre andare con il vincolo di tipo Ord. E 'la più generale, in modo che possa essere riutilizzato più spesso.
Non v'è alcun vantaggio di utilizzare Num su Ord.
Int può avere un piccolo vantaggio in quanto non è polimorfa e non richiederebbe una ricerca dizionario. Vorrei usare STIL Ord e utilizzare il pragma specializzati se avevo bisogno di per le prestazioni.
Modifica:. Alterato la mia risposta dopo i commenti
Dipende da cosa si vuole essere in grado di confrontare. Se si vuole essere in grado di confrontare Double
, Float
, Int
, Integer
e Char
quindi utilizzare Ord
. Se si desidera solo essere in grado di confrontare Int
poi basta usare Int
.
Se avete un altro problema come questo, basta guardare le istanze della classe tipo di dire quale tipo si vuole essere in grado di utilizzare nella funzione.