2013-04-18 14 views
9

Sto studiando Haskell da un po ', quindi sono un principiante.Chiamate polimorfiche Haskell senza una conoscenza completa del tipo

Il seguente codice è facilmente comprensibile:

purStrLn $ show [1] 

Qui possiamo dedurre tutti i tipi (con valori di default), e tutto funziona bene. Ma il seguente codice funziona, troppo:

putStrLn $ show [] 

anche se non siamo in grado di dedurre il tipo di lista.

Se eseguo il codice con ghci ottengo il seguente:

Prelude> [] 
[] 
Prelude> :t it 
it :: [a] 
Prelude> 

modo che il tipo sembra essere polimorfico. Ma in questo caso lo show verrebbe chiamato con un tipo parzialmente applicato.

Lo stesso comportamento è comune con altri tipi, ad esempio con Data.Map.empty, quindi non è una funzionalità di elenco (o almeno sembra così).

Perché e come funziona?

+0

'purStrLn $ spettacolo [1]' deve ancora predefinito a un tipo, come '[1] :: (Num n) => [n]' – amindfv

+0

È vero, ma in casi come questo ci sono dei default. – Totoro

+2

Si noti che qualcos'altro accade quando la variabile di tipo non è vincolata come in es. 'length []', consultare: http://stackoverflow.com/q/7076517. – hammar

risposta

16

Prima di tutto, questo funziona solo in ghci. Se si tenta di compilare questo programma con ghc si otterrà un errore di tipo:

Test.hs:3:19: 
    Ambiguous type variable `a0' in the constraint: 
     (Show a0) arising from a use of `show' 
    Probable fix: add a type signature that fixes these type variable(s) 
    In the second argument of `($)', namely `show []' 
    In the expression: putStrLn $ show [] 
    In an equation for `main': main = putStrLn $ show [] 

Aggiunta di una firma di tipo rende l'errore andare via:

module Main where 

main = putStrLn $ show ([]::[Int]) 

Ma perché ha funzionato in ghci? La risposta è extended type defaulting in ghci: il tipo di a è impostato su () (il tipo di unità).

La motivazione di questo comportamento è che è un po 'noioso per l'utente specificare sempre i tipi quando si lavora nell'interprete. Come Vitus nota nei commenti, in esecuzione ghci con -Wall (o l'aggiunta :set -Wall al vostro ~/.ghci) rende più facile individuare l'inadempiente:

<interactive>:2:12: 
    Warning: Defaulting the following constraint(s) to type `()' 
       (Show a0) arising from a use of `show' 
    In the second argument of `($)', namely `show []' 
    In a stmt of an interactive GHCi command: it <- putStrLn $ show [] 
+3

Inoltre, digitando ': set -Wall' in GHCi aiuta a individuare questo valore predefinito. – Vitus

+0

Ottimo, è una risposta molto esplicativa :) – Totoro

Problemi correlati