2013-07-25 4 views
6

anwenden Was möchte ich erreichen ist:Wie Wert auf eine Liste von Funktionen

apply :: a -> [a -> b] -> [b] 

diese Art der inversen der Karte ist:

map :: (a -> b) -> [a] -> [b] 

Ich habe versucht Hoogle aber ohne Erfolg. Kann jemand in Haskell einen sauberen Weg vorschlagen?

Antwort

15
apply :: a -> [a -> b] -> [b] 
apply a = map ($ a) 

, die eine prägnante Art und Weise ist

sagen
apply a = map (\f -> f a) 

, die mehr klar sein kann.

3

\a -> map ($ a) ist auf jeden Fall in Ordnung, aber vielleicht noch ein bisschen schöner ist ein Applicative Ansatz: Es gibt

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

die <*> :: [a] -> [a->b] -> [b] eine Instanz hat. Sieht viel wie du willst! Sie müssen nur Ihren a Wert in eine Singleton-Liste setzen, für die es auch eine dedizierte Funktion in Applicative: pure gibt.

apply :: Applicative f => a -> f (a -> b) -> f b 
apply = (<**>) . pure 

Obwohl eigentlich, ich würde eher die Signatur a -> [a->b] -> [b] für dieses Top-Level-Bindung beschränken, da Applicative es, wie Sie die allgemeinste Unterschrift möglich haben aussehen lässt, was es nicht ist:

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

Wirklich, meine Lösung ist wahrscheinlich am besten, wenn Sie in irgendeiner Pipeline sind, ich wage es am besten nicht zu definieren apply aber (<**>) . pure direkt im Code verwenden.

+2

Nach den anwendbaren Gesetzen '((<**>). Rein) yu == u <*> rein y == pure ($ y) <*> u == fmap ($ y) für alle' Applicative's, aber die Letzteres ist nur allgemeiner. –

Verwandte Themen