2011-07-16 12 views
6

Ho iniziato a sperimentare con Haskell e ho un problema. qqq è una funzione che dovrebbe stampare una stringa se chiamata con "Nothing" e stampare altre cose se chiamate con "Just something".Uso di "Forse" di Haskell, tipo dichiarazioni [domanda per principianti]

Il primo tentativo sembra di lavoro:

qqq Nothing = print "There isn't anything to be printed." 
qqq (Just x) = print "There is something to be printed." >> print x 

main :: IO() 
main = qqq (Just 43) 

Ma:

  • quando provo a fare main = qqq (Nothing) non riesce ("tipo ambiguo variabile` a0' nel vincolo: (Visualizza a0) derivante da un uso di 'qqq' ")
  • Quando voglio aggiungere tipo di firma se fallisce:
    • qqq :: Maybe x => x -> IO() ->Type constructor 'Maybe' used as a class -> Ma non è vero?
    • qqq :: (Maybe x) -> IO(). Ora la firma stessa sembra avere successo. Ma main = qqq (Just 43) inizia fallendo con quel misterioso errore (Show a0) come nel caso main = qqq (Nothing).

Domande:

  1. Perché chiamare qqq con Nothing è così diverso che chiamare con Just 43?
  2. Che cos'è (Show a0)? Viene menzionato solo nei messaggi di errore. Qualsiasi tentativo di usarlo porta a qualcosa come "Mostra non nell'ambito".
  3. Qual è la firma del tipo corretto per questo? Come si deduce la firma del tipo di stampa Haskell? In attesa di qualcosa di simile a:
f 0 = 2 
f x = (f (x-1)) + 3 

main = print get_type_as_string(f) 
-- prints "Number -> Number" 

risposta

9

Il tipo di qqq è:

qqq :: Show a => Maybe a -> IO() 

Ciò significa che qqq prende un parametro di tipo Maybe a e restituisce un'azione IO senza un valore, con il vincolo che a implementa il typeclass Show. Per scoprire cosa è Show, è possibile utilizzare :i Show in ghci.

Show è un typeclass che richiede che un valore del tipo possa essere convertito in una stringa. qqq ha il vincolo perché print desidera stampare il valore (print ha tipo Show a => a -> IO()). Maybe non è un typeclass ma un tipo di dati. Puoi leggere di più su typeclasses here.

È possibile consentire a GHC di dedurre la firma del tipo digitando la funzione in un file .hs, quindi caricando il file con ghci (ghci Myfile.hs), quindi digitando :t qqq per la visualizzazione del tipo.È anche possibile definire la funzione nella sessione interattiva con let qqq n = case n of { Nothing -> print "abc"; Just x -> print "def" >> print x } (sembra un po 'diverso perché la definizione della funzione deve essere su una riga in ghci, ma il significato è lo stesso).

Quando chiamate principali qqq con qqq (Just 43), è chiaro il tipo concreto di Maybe a è un tipo numerico (default ghci per intero), così qqq ha il tipo concreto di Maybe Integer -> IO(). Tuttavia, le chiamate principali qqq con qqq Nothing, a potrebbero essere qualsiasi cosa (è ambiguo) e ghci segnala un errore.

+0

risposto anche alla domanda non ha chiesto: "Perché non riesco ad impostare nulla in ghci, si lamenta' errore di analisi su '=' '" –

+0

Is "tipo ambiguo" sempre un rifiuto in Haskell o può decidere "il tipo conta qui, quindi lascia che sia ambiguo "a volte? –

+0

Haskell si lamenta di tipi ambigui quando il compilatore non sa cosa fare. Quindi, se il compilatore può scoprire quale sarà il tipo, non ci sono problemi, ma se il tipo deve essere dedotto senza sufficienti informazioni su di esso si ottiene l'errore. – Antti