2012-08-13 8 views
5

¿Cuál es el tipo de return "abc" cuando está impreso en ghci?¿Qué tipo se elige para una expresión polimórfica cuando se imprime?

El punto de la cuestión es que es polimórfico en la mónada:

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

y lo que se imprime depende de la cual se elige mónada:

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

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

pero esto es lo que realmente está impreso:

ghci> return "abc" 
"abc" 
+5

IO. ¡Una sesión de ghci es como una IO Monad especial! – is7s

Respuesta

7

Cuando se escribe una expresión expr en GHCi, sucede lo siguiente:

  • La expresión es de tipo comprobado. Si hay un error, GHCi le dice el error y se da por vencido.
  • De lo contrario, digamos expr tiene el tipo t; GHC intenta hacer coincidir t contra IO a.
  • Si tiene éxito, entonces se ejecuta algo así como it <- expr, entonces si a es una instancia de Show y no () Es decir, se ejecuta print it.
  • Si falla, y t en sí es una instancia de Show, GHCi hace algo así como let it = expr y luego print it.
  • De lo contrario, se queja.

Esencialmente, necesita una forma en el indicador GHCi para ejecutar acciones IO y obtener los valores que devuelve, y jugar con valores puros y ver lo que obtiene. Es por eso que GHCi se comporta de la manera que lo hace: si parece que estás usando una acción IO, GHCi lo hará, y luego si esa acción tiene un resultado que se puede mostrar y es interesante (es decir, no ()), muestra el resultado para ti Si no puede mostrar el resultado para usted, entonces no es gran cosa, porque probablemente solo quiera ejecutar la acción IO de todos modos; si quisiera el resultado, lo habría nombrado con <-. Por otro lado, si parece que su expresión es no una acción IO, GHCi lo calcula y se lo muestra, y si no se puede mostrar, entonces GHCi no puede hacer nada útil (no tiene efectos secundarios) tiempo), así que se queja.

En este caso, return "abc" typechecks como IO String, y String es una instancia de Show, por lo GHCi hace algo como

it <- return "abc" 
print it 

que, por las leyes de las mónadas es exactamente el mismo que acaba de hacer

print "abc" 

de ahí el resultado.

4

Haskell tiene un conjunto de reglas ligeramente desconcertantes para decidir el tipo s de expresiones que involucran números; usted puede ver el Report section on ambiguous types and default instances. Entonces, la respuesta a la pregunta general es complicada. Pero dentro de GHCi, si se introduce una expresión e, se puede confiar en estas reglas a aplicar:

  • Si la expresión e se puede escribir como IO T para algún tipo T, y si T tiene una Show instancia, GHCi ejecutará el cálculo e imprimirá el valor resultante de tipo T. Eso es lo que está sucediendo en tu tercer ejemplo.

  • Si la expresión e * * no puede ser escrito en el IO mónada, entonces las reglas por defecto instancia entran en juego, y GHCi elegirá un tipo de acuerdo con esas reglas. Si el tipo tiene una instancia de Show, GHCi imprimirá showe. Eso es lo que sucede en los dos primeros ejemplos: Maybe String y [String] son valores puros con Show instancias.

    Si el tipo de correos 's hace no tienen una instancia Show, entonces GHCi se quejará. Eso sucederá si escribe una expresión como flip take.

+2

Creo que el hecho de que la pregunta es claramente sobre ghci y las reglas son diferentes hace que las primeras dos oraciones sean engañosas. Además, GHCi no intenta imprimir los resultados de las acciones 'IO' que escribe si el tipo relevante no es' Show'able, o si es '()'. No estoy seguro si no hay más reglas también. Además, las reglas de incumplimiento de GHCi son más fuertes que las de Haskell estándar. –

Cuestiones relacionadas