2012-04-25 7 views
16

Statt fmap, der eine Funktion auf einen Wert-in-a-Funktors gilt:Gibt es einen Namen für diese Funktion oder dieses Muster?

fmap :: Functor f => (a -> b) -> f a -> f b 

I eine Funktion erforderlich, wo der Funktors eine Funktion hat, und der Wert ist klar:

thing :: Functor f => f (a -> b) -> a -> f b 

aber ich can't find one.

Wie heißt dieses Muster, wo ich eine Funktion in einem Funktor (oder in einer Anwendung oder in einer Monade) auf einen einfachen Wert anwende?

Ich habe es bereits implementiert, ich verstehe einfach nicht ganz, was ich getan habe und warum es in den Standardbibliotheken noch nicht so eine Funktion gab.

+4

Ist das nicht nur ein Spezialfall eines Applicative? Wie 'func <*> reiner Wert'? –

+2

Beachten Sie, dass der Typ "ap" und "<*>" sehr ähnlich ist. Obwohl ich keine entsprechende 'Functor'-Version sehe, und dies kann ohne Annahme von' Applicative's oder 'Monad's implementiert werden:' sache fs x = fmap (\ f -> fx) fs' –

+0

Ja, sagt Lambdabot 'Ding = (.pure). (<*>) 'oder' thing = flip (fmap. Flip id) '. Aber ich verstehe, dass dies nicht das ist, was du wissen willst :) –

Antwort

19

Sie brauchen nicht Applicative für diese (?); Functor wird gut tun:

apply f x = fmap ($ x) f 
-- or, expanded: 
apply f x = fmap (\f' -> f' x) f 

Interessanterweise apply ist eigentlich eine Verallgemeinerung von flip; lambdabot ersetzt flip mit dieser Definition als eine seiner Verallgemeinerungen von Standard-Haskell, so dass ein möglicher Name, obwohl ein verwirrender ist.

Übrigens ist es oft einen Versuch wert Hayoo (die im Gegensatz zu Hoogle die gesamte Hackage durchsucht) zu sehen, welche Namen eine Funktion oft gegeben wird, und ob es in einem generischen Paket ist. Auf der Suche nach f (a -> b) -> a -> f b, findet es flip (in Data.Functor.Syntax, aus dem functors Paket) und ($#) (aus dem synthesizer Paket) als mögliche Namen. Trotzdem würde ich wahrscheinlich fmap ($ arg) f an der Verwendungsstelle verwenden.

7

Wie Niklas sagt, ist dies eine Anwendung in einigen Anwendungsfunktoren auf einen gehobenen Wert.

\f a -> f <*> pure a 

:: Applicative f => f (a -> b) -> a -> f b 

oder allgemeiner mit Category(.)

\f a -> f . pure a 

:: (Applicative (cat a), Category cat) => cat b c -> b -> cat a c 
Verwandte Themen