2012-08-13 14 views
5

Qual è il tipo di return "abc" se stampato in ghci?Quale tipo viene scelto per un'espressione polimorfa quando viene stampato?

Il punto della questione è che è polimorfa nella monade:

ghci> :t return "abc" 
return "abc" :: (Monad m) => m [Char] 

e ciò che viene stampato dipende da quale viene scelto monade:

ghci> return "abc" :: Maybe String 
Just "abc" 

ghci> return "abc" :: [] String 
["abc"] 

ma ecco ciò che è effettivamente stampato:

ghci> return "abc" 
"abc" 
+5

IO. Una sessione ghci è come una speciale enorme IO Monade! – is7s

risposta

7

Quando si digita un'espressione expr in GHCi, le seguenti cose accadono:

  • L'espressione è di tipo controllato. Se c'è un errore, GHCi ti dice l'errore e si arrende.
  • In caso contrario, ad esempio expr è stato trovato il tipo t; GHC cerca di far corrispondere lo t allo IO a.
  • Se riesce, esegue qualcosa come it <- expr, quindi se a è un'istanza di Show e non è (), viene eseguito print it.
  • Se non riesce e t è un'istanza di Show, GHCi fa qualcosa come let it = expr e quindi print it.
  • Altrimenti, si lamenta.

In sostanza, è necessario un modo al GHCi di eseguire sia azioni IO che ottenere i valori restituiti, e di giocare con valori puri e vedere ciò che si ottiene. Ecco perché GHCi si comporta come fa: se sembra che tu stia usando un'azione IO, GHCi lo farà, e poi se quell'azione ha un risultato che può essere mostrato ed è interessante (cioè non ()) allora mostra risultato per te. Se non è in grado di mostrarti il ​​risultato, non è un grosso problema, perché probabilmente hai semplicemente voluto eseguire l'azione IO comunque; se volessi il risultato lo avresti chiamato con <-. D'altra parte, se sembra che la tua espressione sia non un'azione IO, GHCi la calcola e te la mostra, e se non può essere mostrata, GHCi non può fare nulla di utile (senza effetti collaterali questo tempo), così si lamenta.

In questo caso, return "abc" typechecks come IO String, e String è un'istanza di Show, così GHCi fa qualcosa di simile

it <- return "abc" 
print it 

che dalle leggi monade è esattamente lo stesso che solo facendo

print "abc" 

quindi il risultato.

4

Haskell ha un insieme un po 'sconcertante di regole per decidere il tipo s di espressioni che coinvolgono numeri; puoi vedere lo Report section on ambiguous types and default instances. Quindi la risposta alla domanda generale è complicata. Ma all'interno GHCi, se si immette un'espressione e, si può fare affidamento su queste regole da applicare:

  • Se l'espressione e può essere digitato come IO T per un certo tipo T, e se T ha un Show istanza, GHCi eseguirà il calcolo e stamperà il valore risultante di tipo T. Questo è ciò che sta accadendo nel tuo terzo esempio.

  • Se l'espressione e * non può * essere digitato nel IO Monade, allora le regole predefinite istanza entrano in gioco, e GHCi sceglierà un tipo in base a tali norme. Se il tipo ha un'istanza Show, GHCi stamperà quindi showe. Questo è ciò che accade nei tuoi primi due esempi: Maybe String e sono valori puri con istanze Show.

    Se tipo e l' fa non hanno un'istanza Show, quindi GHCi si lamenta. Ciò avverrà se si digita un'espressione come flip take.

+2

Penso che il fatto che la domanda riguardi chiaramente i ghci e le regole siano diverse, rende le prime frasi fuorvianti. Inoltre, GHCi non tenta di stampare i risultati delle azioni 'IO' che scrivi se il tipo rilevante non è' Show'able, o se è '()'. Non sono sicuro che non ci siano più regole. Inoltre, le regole di default di GHCi sono più forti di quelle standard di Haskell. –

Problemi correlati