simbolos pattern opciones mundo hola hacer ejemplos como ciclos haskell types

opciones - pattern matching haskell



¿Cuál es el tipo de Nada en Haskell? (5)

Estoy en la página 118 del libro "Learn You a Haskell for Great Good!"

Está escrito allí:

ghci> :t Nothing Nothing :: Maybe a

Aquí está mi pregunta:

Si entiendo correctamente, Nothing es un valor y solo los tipos concretos pueden tener valores, pero Maybe a no sea un tipo concreto. Entonces, ¿cómo puede tener el valor Nothing ?

El libro también dice:

Note que el tipo de Nada es Tal vez a. Su tipo es polimórfico.

¿Qué significa tipo polimórfico? ¿Cómo debo entender esto? ¿No está esto en contradicción con la regla de que solo los tipos concretos pueden tener valores?

EDITAR:

De la versión PDF del libro:

Decimos que un tipo es concreto si no toma ningún tipo de parámetros (como Int o Bool), o si toma parámetros de tipo y todos están rellenados (como Maybe Char). Si tienes algún valor, su tipo es siempre un tipo concreto.


¿No está esto en contradicción con la regla de que los únicos tipos concretos pueden tener valores?

Dado que las funciones son valores de primera clase en Haskell, esta supuesta regla significaría que las funciones polimórficas como map y foldr serían imposibles de implementar.

De hecho, hay muchos valores no funcionales polimórficos en Haskell, como

1 :: Num a => a Nothing :: Maybe a [] :: [a] Left 1 :: Num a => Either a b

Estos valores existen para cada instanciación de a (y b ).


El tipo Maybe tiene dos constructores: Nothing y Just a, donde a es una variable de tipo. Nada en sí mismo no determina (restringe) el tipo, pero en cualquier contexto razonable encontrará algo como (no pretendo que sea un Haskell sintácticamente correcto sino algo que hubiera escrito hace 10 años):

if (foo == 5) then Nothing else Just 5

Y luego la inferencia de tipos le dirá que (suponga que 5 era un argumento de este fragmento de código ''foo'' de tipo Int) que foo tiene tipo:

foo :: Int -> Maybe Int

Pero como señaló el póster anterior, Quizás a es un tipo perfectamente bueno. Encontrará el mismo problema con [], es decir, el tipo de lista con [] (el constructor para una lista vacía).


En cierto sentido, tienes razón. No hay valores de tipo para todos forall a.Maybe a . Cada valor de Maybe que construyas tendrá un tipo definido. Maybe tau , donde tau puede ser conocido o no, pero es un tipo definido.

La notación Nothing :: forall a.Maybe a just nos dice que siempre que usemos la expresión Nothing , construirá un valor del tipo Maybe esperado.


No está en contradicción. Nothing es un valor, y su tipo concreto puede ser cualquier posible instanciación de Maybe a .

Dicho de otro modo, los valores de tipo Maybe a sigan teniendo tipos concretos Maybe Int , Maybe String , Maybe Whatever , y en particular, Nothing puede ser escrito por cada uno de ellos, según el contexto. Esto se debe a que su constructor, que nuevamente se llama Nothing :: Maybe a , no toma ningún parámetro y, por lo tanto, se puede llamar as-is para generar valores de tipo Maybe a . Tendremos uno por tipo concreto, si lo desea.

Sin un contexto, por supuesto, ghci le dará el tipo más general que puede inferir para Nothing , que es Maybe a , pero no es su tipo concreto. Eso dependerá de las expresiones individuales en las que usará Nothing . Por ejemplo:

ghci> Nothing Nothing it :: Maybe a

Esto es lo que probablemente escribiste, o algo así. No hay más contexto, por lo tanto, Nothing se escribe con un tipo concreto.

ghci> Nothing :: Maybe Int Nothing it :: Maybe Int

Aquí lo forcé a asumir el tipo concreto Maybe Int .

ghci> 1 + fromMaybe 2 Nothing 3 it :: Integer

Si lo mezclo con una suma de enteros ( fromMaybe :: a -> Maybe a -> a toma un valor predeterminado y a Maybe a y devuelve el valor en Just o el predeterminado con Nothing ), entonces Nothing se escribirá como Maybe Integer por el sistema, ya que espera extraer un entero de él. No hay ninguno, por lo que en este caso sumamos 1 con el valor predeterminado 2.

ghci> 1 + fromMaybe 2 (Nothing :: Maybe Integer) 3 it :: Integer

Lo mismo aquí, para volver a comprobar. No Nothing a Nothing a tener el tipo concreto que asumimos que tenía antes en la misma expresión.

ghci> 1 + fromMaybe 2 (Nothing :: Maybe Char) <interactive>:1:15: No instance for (Num Char) arising from the literal `2'' Possible fix: add an instance declaration for (Num Char) In the first argument of `fromMaybe'', namely `2'' In the second argument of `(+)'', namely `fromMaybe 2 (Nothing :: Maybe Char)'' In the expression: 1 + fromMaybe 2 (Nothing :: Maybe Char)

Para realizar una triple comprobación, si lo forzamos a asumir otro tipo concreto, como verán, su valor será completamente diferente, lo que resultará en un error de tipo (a diferencia de C, en Haskell Char no actúa como un número).


This charla a las 26:00 responde la pregunta: "¿cuál es el tipo de [ ] ?" que es una pregunta relacionada con "¿Cuál es el tipo de Nothing ?".

También el libro de Hudak tiene un bonito párrafo sobre esto: