9

Was ist die allgemeine Bezeichnung für eine Funktors promote mit einer Struktur ähnlich der Funktion Quick Check, das heißt eine Funktion der Form:Was ist der allgemeine Fall der Promotion-Funktion von QuickCheck?

promote :: (a -> f b) -> f (a -> b) 

(dies ist die Umkehrung von flip $ fmap (flip ($)) :: f (a -> b) -> (a -> f b)). Gibt es überhaupt irgendwelche Funktoren mit solch einer Operation, außer (->) r und Id? (Ich bin sicher, dass es da sein muss). Googeln 'Quickcheck promote' zeigte nur die QuickCheck-Dokumentation, die promote in keinem allgemeineren Kontext AFAICS gibt; Suche nach SO für "Quickcheck promote" führt zu keinen Ergebnissen.

+0

Ist ['sequenceA'] (http://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Traversable.html#v:sequenceA) relevant? –

+0

Lass mich sehen. Wenn wir in den Typ von 'sequenceA' einwechseln, würden wir' t = (->) a' und 'f = f' erhalten. Wenn also "(->) a" eine "Traversable" -Instanz hätte, würde diese Funktion für alle "a" existieren. Ich denke 'Traversable ((->) a)' erfordert '(Bounded a, Enum a)' von oder das Äquivalent, obwohl. –

+1

Für was es wert ist, bietet die Paketfamilie [universum] (http://hackage.haskell.org/package/universe) die [erforderliche 'Traversable'-Instanz] (http://hackage.haskell.org/package/universe -reverse-instances-1.0/docs/src/Datenuniverse-Instanzen-Traversable.html). –

Antwort

1

Bisher fand ich diese Möglichkeiten, einen f mit dem promote morphism Konstruktion:

  • f = Identity
  • wenn f und g beide haben promote dann das Paar Funktors h t = (f t, g t) auch tut
  • wenn f und g beide haben promote dann die h t = f (g t) auch tut
  • wenn f hat die promote Eigenschaft und g ist ein y contrafunctor dann der Funktors h t = g t -> f t hat die promote Eigenschaft

Die letzte Eigenschaft kann auf profunctors g verallgemeinert werden, aber dann wird f sein nur ein profunctor, so ist es wahrscheinlich nicht sehr nützlich, wenn Sie nur profunctors benötigen.

nun diese vier Konstruktionen verwenden, können wir viele Beispiele für functors f für die promote existiert finden:

f t = (t,t) 

f t = (t, b -> t) 

f t = (t -> a) -> t 

f t = ((t,t) -> b) -> (t,t,t) 

f t = ((t, t, c -> t, (t -> b) -> t) -> a) -> t 

Beachten Sie auch, dass die promote Eigenschaft impliziert, dass f gerichtet ist.

point :: t -> f t 
point x = fmap (const x) (promote id) 

Wesentlichen die gleiche Frage: Is this property of a functor stronger than a monad?

5
(<*>) :: Applicative f => f (a -> b) -> f a -> f b 
(=<<) :: Monad m => (a -> m b) -> m a -> m b 

Da Monad mächtiger als eine Schnittstelle Applicative ist, das sagt uns, dass a -> f b als f (a -> b) mehr Dinge tun können. Dies zeigt uns, dass eine Funktion vom Typ (a -> f b) -> f (a -> b) nicht injektiv sein kann. Die Domäne ist handwavey größer als der Codomain. Dies bedeutet, dass Sie das Verhalten der Funktion möglicherweise nicht beibehalten können. Es funktioniert einfach nicht über generische Funktoren.

Sie können natürlich Funktoren charakterisieren, in denen diese Operation injektiv ist. Identity und (->) a sind sicherlich Beispiele. Ich wette, dass es mehr Beispiele gibt, aber mir springt nichts sofort auf.

1

Data.Distributive hat

class Functor g => Distributive g where 
    distribute :: Functor f => f (g a) -> g (f a) 
    -- other non-critical methods 

Ihre Variablen umbenennen, erhalten Sie

promote :: (c -> g a) -> g (c -> a) 

Klarheit für etwas ungültige Syntax verwenden,

promote :: ((c ->) (g a)) -> g ((c ->) a) 

(c ->) ist ein Functor, so dass die Art von promote ist ein Spezialfall von der Art der distribute. So unterstützt jeder Funktor Distributive Ihren promote. Ich weiß nicht, ob irgendwelche Unterstützung promote, aber nicht Distributive.

+2

'Distributive' ist streng stärker als' promote'. Jeder 'Distributiv'-Funktor' g' ist darstellbar, dh es existiert eine Konstante vom Typ 'b', so dass' g t = b -> t '. Funktoren wie "g t = (t -> a) -> t" haben jedoch "fördern", sind aber nicht darstellbar und daher nicht "distributiv". Allgemeiner gesagt, hat ein Funktor 'g' definiert als' g t = c t -> h t ''promote', wenn 'c' irgendein Konstruktor ist und' h ''promote. Diese Konstruktion kann nur dann ein Verteilbares definieren, wenn "c" ein konstanter (Gegen-) Funktor ist. – winitzki