2015-07-05 11 views
8

Qualcuno può spiegare che cosa manco qui:riguardanti il ​​tipo classi Haskell (Num vs Read)

Prelude> :t read 
read :: (Read a) => String -> a 
Prelude> read "4" 

<interactive>:1:0: 
    Ambiguous type variable `a' in the constraint: 
     `Read a' arising from a use of `read' at <interactive>:1:0-7 
    Probable fix: add a type signature that fixes these type variable(s) 

read "4" genera un errore come ghci non sa quale tipo concreto che vogliamo, si sa solo che ci avere una classe di tipo Read. read "4" :: Int funziona bene. Questo è chiaro per me.

Ora, seguendo la logica di cui sopra, mi aspettavo fromIntegral 4 a sollevare un errore:

Prelude> :t fromIntegral 
fromIntegral :: (Integral a, Num b) => a -> b 
Prelude> fromIntegral 4 
4 

Tuttavia, funziona benissimo. Perché in questo caso non è richiesto un tipo annotaion? Mi aspettavo che quanto sopra avesse esito negativo; e SOLO

Prelude> fromIntegral 4 :: Int 

al lavoro.

NB - Sto leggendo "Learn you a Haskell per great good" e ho coperto fino al capitolo 5. È quello che chiedo discusso nel capitolo 7 (o in qualche altro capitolo)?

Grazie.

risposta

12

Funziona a causa di type defaulting, che causa l'impostazione predefinita di variabili di tipo ambigue a Integer o Double (o qualche altro predefinito definito dall'utente). Questo accade solo per Num e le sue sottoclassi.

In GHCi, the rules for defaulting are relaxed a lavorare anche per Show, Eq e Ord, e si aggiunge anche () alla lista dei tipi predefiniti. Ciò consente espressioni come [] == [] per la verifica del tipo.

4

La differenza è che la lettura potrebbe potenzialmente dare origine a qualsiasi tipo, mentre da Integrale produce un numero. Ci sono alcune impostazioni predefinite relative ai numeri in ghci, in modo che ghci possa semplicemente usare il tipo predefinito.