haskell functor applicative higher-kinded-types

haskell - Funciones y aplicativos para tipos de tipo(*->*)->*



functor applicative (1)

El HFunctor que tiendo a pensar es (* -> *) -> * -> * - es decir, un funtor legítimo en los funtores. Esto tiene características diferentes a las que estás pensando.

Aquí se explica cómo definirlo, así como la versión "monoidal" de un aplicativo.

type Nat f g = forall a. f a -> g a class HFunctor (f :: (* -> *) -> * -> *) where hfmap :: (Nat g h) -> Nat (f g) (f h) data Prod f g a = Prod (f a) (g a) class HFunctor f => HApplicative f where hpure :: Nat g (f g) htensor :: Nat (Prod (f g) (f h)) (f (Prod g h))

Intentaré actualizar más adelante con algunas ideas sobre qué es esto y cómo usarlo.

Esto no es exactamente lo que estás pidiendo, me doy cuenta, pero me inspiré para probarlo en tu publicación.

También me interesaría su caso de uso específico.

A sus dos preguntas específicas A) El HFunctor que describe ha sido descrito anteriormente en varias ocasiones, creo que en particular por Gibbons, pero no sé si está empaquetado. Ciertamente no he visto el aplicativo antes. B) Creo que estás atascado con el envoltorio porque no podemos aplicar parcialmente los sinónimos de tipo.

Me encontré con una situación en la que mi código se beneficiaría con el uso de abstracciones similares a Functor y Applicative , pero para tipos de tipo (* -> *) -> * . La definición de un funtor de tipo superior se puede hacer con RankNTypes como este

class HFunctor f where hfmap :: (forall x. a x -> b x) -> f a -> f b

Pero la versión superior de Applicative es un poco más complicada. Esto es lo mejor que se me ocurre:

class HFunctor f => HApplicative f where hpure :: (forall x. a x) -> f a (<**>) :: f (a :-> b) -> f a -> f b newtype (:->) a b x = HFunc (a x -> b x) infixr 5 :->

Necesitamos el :-> tipo de envoltura para tener funciones con el tipo * -> * , pero esto no nos permite encadenar la aplicación de la función como podemos con <$> y <*> para los aplicativos normales. Puedo manejar con ayudante como

liftHA2 :: HApplicative f => (forall x. a x -> b x -> c x) -> f a -> f b -> f c liftHA2 f fa fb = hpure (fun2 f) <**> fa <**> fb where fun2 = HFunc . (HFunc .)

Pero sería bueno tener una forma general de "levantar" las funciones de cualquier aridad.

Algunos ejemplos simples de cómo se pueden usar las instancias anteriores:

data Example f = Example (f Int) (f String) instance HFunctor Example where hfmap f (Example i s) = Example (f i) (f s) instance HApplicative Example where hpure a = Example a a Example (HFunc fi) (HFunc fs) <**> Example i s = Example (fi i) (fs s) e :: Example [] e = Example [1,2,3] ["foo", "bar"] e'' :: Example ((,) Int) e'' = hfmap (length &&& head) e -- Example (3,1) (2, "foo") e'''' :: Example [] e'''' = liftHA2 (++) e e -- Example [1,2,3,1,2,3] ["foo", "bar", "foo", "bar"]

Entonces, mi pregunta es: ¿cómo se llaman las clases de tipos anteriores y ya están provistas por alguna biblioteca en hackage? Al Functor2 en Google encontré Functor2 en linear-maps y HFunctor en multi-rec pero ninguno de los dos hace exactamente lo que necesito.

Además, ¿hay alguna forma de escribir HApplicative sin la :-> envoltura o alguna otra forma de facilitar el levantamiento de funciones?