Pregunta

Esta pregunta surgió al leer el nuevo capítulo en el excelente Learn You a Haskell sobre los funcionadores aplicativos.

La clase de tipo Aplicativo tiene, como parte de la definición de la instancia de Maybe:

pure = Just

Si solo voy a GHCi e importo Control.Applicative, y hago:

pure (3+)

No obtengo nada (tiene sentido). Pero si lo uso en parte de la expresión:

pure (3+) <*> Just 4

Recibo Just 7. Supongo que tampoco es sorprendente, pero me falta algo integral sobre cómo funcionan las clases de tipos, creo que no hay ambigüedad con la llamada a pure aquí.

Si mi confusión tiene sentido, ¿alguien puede explicar lo que está sucediendo en detalle?

¿Fue útil?

Solución

Es solo inferencia de tipos. El operador (<*>) requiere que ambos argumentos utilicen la misma instancia Applicative. El lado derecho es un Maybe, por lo que el lado izquierdo también debe ser un :t expression. Así es como se determina qué instancia se usa aquí. Puede ver el tipo de cualquier expresión en el intérprete escribiendo <=>, y tal vez si solo revisa cada subexpresión y mira el tipo que se infirió, obtendrá una mejor idea de lo que está sucediendo.

Otros consejos

Vale la pena mirar el tipo que infiere el compilador para pure (3+):

Prelude Control.Applicative> :t pure (3+)
pure (3+) :: (Num a, Applicative f) => f (a -> a)

El tipo de este término está sobrecargado, y la decisión sobre la clase numérica y la clase aplicativa se retrasa hasta más tarde. Pero puede forzar un tipo particular con una anotación, por ejemplo:

*Showfun Control.Applicative> pure (3+) :: Maybe (Double -> Double)
Just <function>

(Esto funciona porque Showfun tiene una declaración de instancia que imprime un valor de función como <function>.)

Es solo una cuestión de cuándo el compilador ha acumulado suficiente información para tomar una decisión.

Para ampliar un poco la respuesta de newacct, si no hay suficiente información para inferir el tipo real, el compilador puede (en algunos casos) intentar seleccionar un tipo predeterminado, limitado a aquellos que satisfagan las restricciones de tipo en cuestión . En este caso, el tipo inferido es IO (n - & Gt; n) para alguna instancia difícil de determinar de Num = & Gt; norte. GHCi lo evalúa y tira el valor de retorno, sin efecto visible.

Aquí hay un hilo SO en la inferencia de tipos interesante. No es específico de Haskell, pero hay muchos enlaces buenos y cosas para leer sobre inferencia de tipos en lenguajes funcionales.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top