2013-08-05 8 views
20

Ich lief in einer Situation, in der mein Code von der Verwendung Functor und -ähnliche Abstraktionen profitieren würde, aber für Arten von Art (* -> *) -> *. eine höhere kinded Funktors definieren kann mit RankNTypes wie dieseFunktoren und Applicates für Arten von Art (* -> *) -> *

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

Aber je höher Art Version von Applicative ist ein bisschen schwieriger durchgeführt werden. Dies ist das Beste, was ich tun konnte,:

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 :-> 

Wir brauchen die :-> Wrapper um Funktionen zu haben, mit der Art * -> *, aber das hat uns nicht gut Anwendungskette Funktion lassen wie wir können mit <$> und <*> für normale Anwendungen. Ich kann mit Helfer wie

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 .) 

verwalten Aber es wäre schön, einen allgemeinen Weg, um zu „heben“ Funktionen jeder Stelligkeit.

Einige einfache Beispiele, wie die obigen Beispiele verwendet werden können:

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"] 

Also, meine Frage ist: Was sind die oben typeclasses genannt und werden sie bereits von einigen Bibliothek in Hackage zur Verfügung gestellt? Beim googeln kam ich mit Functor2 in linear-maps und HFunctor in multi-rec, aber keiner tut genau was ich brauche.

Gibt es auch eine Möglichkeit, HApplicative ohne die :-> Wrapper oder eine andere Möglichkeit, Funktion Heben leichter zu schreiben?

Antwort

2

Der HFunctor, den ich denke, ist (* -> *) -> * -> * - also ein legitimierter Funktor auf Funktoren. Dies hat andere Eigenschaften als die, an die Sie denken.

Hier ist, wie Sie es definieren, sowie die "monoidale" Version eines Anwenders auf ihm.

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)) 

Ich werde versuchen, später mit einigen Ideen zu aktualisieren, was das ist und wie man es benutzt.

Dies ist nicht genau das, wonach Sie fragen, ich weiß, aber ich wurde inspiriert, es mit Ihrer Post auszuprobieren.

Ich würde auch in Ihrem spezifischen Anwendungsfall interessiert sein.

Zu deinen zwei spezifischen Fragen A) Der HFunctor, den du beschreibst, wurde schon mehrmals beschrieben, denke ich vor allem an Gibbons, aber ich weiß nicht, wie er verpackt ist. Ich habe den Applicative sicherlich noch nicht gesehen. B) Ich denke, Sie sind mit dem Wrapper festgefahren, weil wir teilweise Synonyme nicht anwenden können.

+0

Der Unterschied ist, dass Sie Endo-Funktoren definieren, während das OP Funktoren aus einer Kategorie definiert, in der Objekte eine Art '* -> *' (vielleicht sollte dies die Kategorie von Endo-Funktoren auf Hask sein) zu Hask. –

+0

Richtig - wie ich bemerkte "hat dies andere Eigenschaften als die, an die Sie denken". – sclv

+0

Nur ein kleiner technischer Kommentar: 'f :: (* -> *) -> * -> *' ist kein "Funktor auf Funktoren", auch wenn 'f' ein' HFunctor' ist, weil '* -> * 'stellt nur alle Typkonstruktoren dar, sie müssen nicht selbst Funktoren sein.Zum Beispiel ist das "a: -> b" des OP im Allgemeinen kein Funktor, selbst wenn "a" und "b" sind (du willst, dass "a" ein kontravarianter Funktor ist). Ich habe fast ein paar sehr falsche Dinge geschrieben, bevor ich mich daran erinnere ... –

Verwandte Themen