2011-07-16 11 views
6

Comencé a experimentar con Haskell y tengo un problema. qqq es una función que debería imprimir una cadena si se llama con "Nothing" e imprimir otras cosas si se llama con "Just something".Usando Haskell "Quizás", escriba declaraciones [pregunta del principiante]

El primer intento parece de trabajo:

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) 

Pero:

  • cuando trato de hacer main = qqq (Nothing) se produce un error ("tipo ambiguo variables` a0' en la restricción: (Mostrar a0) gracias a la utilización de 'qqq' ")
  • Cuando quiero añadir tipo de firma si falla:
    • qqq :: Maybe x => x -> IO() ->Type constructor 'Maybe' used as a class -> ¿Pero no es así?
    • qqq :: (Maybe x) -> IO(). Ahora la firma en sí parece tener éxito. Pero main = qqq (Just 43) comienza a fallar con ese error misterioso (Show a0) como en el caso main = qqq (Nothing).

Preguntas:

  1. Por qué llamar qqq con Nothing es tan diferente a la que llama con Just 43?
  2. ¿Qué es (Show a0)? Se menciona solo en los mensajes de error. Cualquier intento de usarlo conduce a algo así como "Mostrar no en el alcance".
  3. ¿Cuál es la firma de tipo de letra correcta para esto? ¿Cómo se deduce la firma del tipo de impresión Haskell? Esperando algo como:
f 0 = 2 
f x = (f (x-1)) + 3 

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

Respuesta

9

El tipo de qqq es:

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

Eso significa que qqq toma un parámetro de tipo Maybe a y devuelve una acción IO sin valor, con la restricción que a implementa la clase de tipo Show. Para saber qué es Show, puede usar :i Show en ghci.

Show es una clase de tipo que requiere que un valor del tipo se pueda convertir a una cadena. qqq tiene la restricción porque print desea imprimir el valor (print tiene tipo Show a => a -> IO()). Maybe no es una clase de tipo sino un tipo de datos. Puede leer más sobre las clases de tipos here.

Puede dejar que GHC deduzca la firma de tipo ya sea escribiendo la función en un archivo .hs, luego cargando el archivo con ghci (ghci Myfile.hs) y escribiendo :t qqq para mostrar el tipo.También puede definir la función en la sesión interactiva con let qqq n = case n of { Nothing -> print "abc"; Just x -> print "def" >> print x } (se ve un poco diferente porque la definición de la función debe estar en una línea en ghci, pero el significado es el mismo).

Cuando las llamadas principales qqq con qqq (Just 43), está claro el tipo concreto de Maybe a es un tipo numérico (por defecto ghci a un entero), por lo qqq tiene el tipo concreto de Maybe Integer -> IO(). Sin embargo, las llamadas principales qqq con qqq Nothing, a podrían ser cualquier cosa (es ambigua) y ghci informa de un error.

+0

También respondió la pregunta no hecha "Por qué no puedo establecer nada en ghci, se queja' parse error on '=' '" –

+0

Es "ambiguo tipo" siempre falla en Haskell o puede decidir "el tipo importa aquí, así que deje que sea ambiguo "a veces" –

+0

Haskell se queja de tipos ambiguos cuando el compilador no sabe qué hacer. Entonces, si el compilador puede averiguar cuál será el tipo, no hay problema, pero si el tipo debe inferirse sin suficiente información, se obtiene el error. – Antti

Cuestiones relacionadas