2012-10-07 12 views
20

Questa funzione:Num vs integrale

hola :: (Integral a) => a -> String 
hola 1 = "OK" 
hola _ = "asdf" 

funziona bene. Ma questo:

hola :: (Num a) => a -> String 
hola 1 = "OK" 
hola _ = "asdf" 

non può essere compilato: "Impossibile dedurre (Eq a) derivante dalla letterale` 1' "

Io davvero non capisco. Sto leggendo un tutorial dove è detto

"Integral è anche un typeclass numerico. Num comprende tutti i numeri, compresi i numeri reali e numeri interi, Integral include solo numeri interi (interi). In questo typeclass sono Int e Numero intero." http://learnyouahaskell.com/types-and-typeclasses

Perché non posso utilizzare Num?

risposta

27

È un cambiamento recente proposed and accepted in September/October last year, nella sua ultima versione del pacchetto di base, Eq e Show non sono più superclassi di Num. Da quel cambiamento, non è stata pubblicata nessuna nuova versione del rapporto linguistico, quindi non è ancora presente nel rapporto. E dal momento che è recente, non è ancora entrato in molti tutorial o libri.

"La corrispondenza del modello" con un valore letterale numerico è un'applicazione implicita di (==), pertanto è necessaria un'istanza Eq perché funzioni. L'istanza non può più essere desunta dal vincolo Num, quindi il compilatore (abbastanza nuovo: D) rifiuta il codice con un solo vincolo Num.

Ma Integral è una sottoclasse di Real, che ha Ord (e quindi Eq) come superclasse, quindi che funziona.

+0

Lavorare nella versione precedente :) Grazie !! Penso che questo cambiamento faccia un po 'confondere questo linguaggio. :( – user1726613

+0

Beh, causerà sicuramente molta confusione (e la rottura dei pacchetti) nel periodo di transizione, ma il consenso generale è che il guadagno è maggiore della perdita (non più spurie 'Eq' e' Show' per cose come funzioni che possono avere istanze 'Num' sensibili ad eccezione dei vecchi requisiti' Eq' e 'Show'.) Lo stesso (mutatis mutandis) si applica alla rimozione di' Num. Superclasse da 'Bits' .Per fortuna, le rotture sono _backward-compatibilmente_ corrette aggiungendo i vincoli –

+0

Grazie mille Daniel, le tue risposte sono state molto utili.Così con il nuovo compilatore devo assicurarmi che il vincolo includa un Eq istanza almeno per fare il confronto – user1726613

4

Come ha detto Daniel Fischer, ha usato per lavorare, ma ora non funziona perché Num e Eq sono stati divisi in modo Num a non implica più Eq a. Per correggere il codice, è sufficiente creare Eq a esplicito:

hola :: (Num a, Eq a) => a -> String 
hola 1 = "OK" 
hola _ = "asdf"