name keywords generar etiquetas ejemplos como haskell functional-programming

haskell - keywords - meta tags generator



Un ejemplo de un tipo con tipo*->*que no puede ser una instancia de Functor (3)

Para ampliar mi (breve) comentario y la respuesta de Mikhail:

Dado (-> Int) , esperaría que fmap vea como tal:

(a -> Int) -> (a -> b) -> (b -> Int)

o:

(a -> Int) -> (a -> b) -> b -> Int

Es fácil demostrar que a partir de los tres argumentos (a -> Int) , (a -> b) , b no hay forma posible de llegar a Int (sin undefined ), por lo tanto de (a -> Int) , (a -> b) no hay forma de llegar (b -> Int) . Conclusión: no existe una instancia de Functor para (-> Int) .

Soy un principiante de Haskell, por lo que me disculpo si la respuesta es obvia, pero estoy trabajando en Typeclassopedia para comprender mejor las categorías. Al hacer los ejercicios para la sección de Functors, encontré este problema:

Dé un ejemplo de un tipo de tipo * -> * que no se pueda convertir en una instancia de Functor (sin usar indefinido).

Mi primer pensamiento fue definir algún tipo de definición infinitamente recurrente de fmap, pero ¿no sería eso esencialmente lo mismo que si undefined se usara undefined en la definición?

Si alguien pudiera explicar la respuesta sería muy apreciado.

¡Gracias!

Fuente del ejercicio original aquí, sección 3: http://www.haskell.org/haskellwiki/Typeclassopedia#Introduction


También tuve problemas con este, y encontré las respuestas de Ramon y Mikhail informativas, ¡gracias! Estoy poniendo esto en una respuesta en lugar de un comentario porque 500 caracteres es demasiado corto, y para el formato de código.

Estaba teniendo problemas para entender qué era la covariante de (a -> Int) y se me ocurrió este contraejemplo que muestra que los data K a = K (a -> Int) pueden ser una instancia de Functor (refutando la prueba de Ramon)

data K a = K (a -> Int) instance Functor K where fmap g (K f) = K (const 0)

Si se compila, debe ser correcto, ¿verdad? ;-) Pasé algún tiempo probando otras permutaciones. Darle la vuelta a la función simplemente lo hizo más fácil:

-- "o" for "output" -- The fmapped (1st) type is a function output so we''re OK. data K0 o = K0 (Int -> o) instance Functor K0 where fmap :: (oa -> ob) -> (K0 oa) -> (K0 ob) fmap g (K0 f) = K0 (g . f)

Convertir el Int en una variable tipo lo redujo a la Sección 3.2, ejercicio 1, parte 2:

-- The fmapped (2nd) type argument is an output data K1 a b = K1 (a -> b) instance Functor (K1 a) where fmap :: (b1 -> b2) -> K1 a b1 -> K1 a b2 fmap g (K1 f) = K1 (g . f)

Forzar al tipo fmapped a ser un argumento de la función fue la clave ... tal como dijo la respuesta de Mikhail, pero ahora lo entiendo ;-)

-- The fmapped (2nd) type argument is an input data K2 a b = K2 (b -> a) instance Functor (K2 o) where fmap :: (ia -> ib) -> (K2 o ia) -> (K2 o ib) -- Can''t get our hands on a value of type o fmap g (K2 f) = K2 (const (undefined :: o)) -- Nor one of type ia fmap g (K2 f) = K2 (const (f (undefined :: ia)))


Un ejemplo simple es

data K a = K (a -> Int)

Esto es lo que ghci nos dice que intentamos derivar automáticamente una instancia de Functor para K :

Prelude> :set -XDeriveFunctor Prelude> data K a = K (a -> Int) Prelude> :k K K :: * -> * Prelude> data K a = K (a -> Int) deriving Functor <interactive>:14:34: Can''t make a derived instance of `Functor K'': Constructor `K'' must not use the type variable in a function argument In the data type declaration for `K''

El problema es que la clase Functor estándar en realidad representa funtores covariantes ( fmap eleva su argumento a fa -> fb ), pero no hay forma de que pueda componer a -> b a -> Int para obtener una función de tipo b -> Int (ver la respuesta de Ramón). Sin embargo, es posible definir una clase de tipo para los funtores contravariantes:

class Contravariant f where contramap :: (a -> b) -> f b -> f a

y haz de K un ejemplo de ello:

instance Contravariant K where contramap f (K g) = K (g . f)

Para más información sobre la covarianza / contravarianza en Haskell, consulte here .

Edición: Aquí también hay un buen comentario sobre este tema de Chris Smith en Reddit.