2013-07-25 17 views
6

Quello che mi piacerebbe realizzare è:Come applicare un valore a un elenco di funzioni

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

questo è una specie di l'inverso della carta:

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

ho provato Hoogle , ma senza risultato. Qualcuno può suggerire un modo pulito per farlo in Haskell?

risposta

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

che è un modo conciso per dire

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

che potrebbe essere più chiaro.

3

\a -> map ($ a) è sicuramente bene, ma forse ancora un po 'più è un approccio Applicative: c'è

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

che dispone di un'istanza <*> :: [a] -> [a->b] -> [b]. Sembra molto come quello che vuoi! Devi solo inserire il tuo valore a in un elenco singleton, per il quale esiste anche una funzione dedicata in Applicative: pure.

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

Anche se in realtà, avrei preferito limitare la firma a -> [a->b] -> [b] per questo legame di livello superiore, in quanto Applicative rende simile si ha la firma più generale possibile, che non è:

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

In realtà, la mia soluzione è probabilmente la migliore quando si è in una pipeline, suppongo che sia meglio non definire apply ma utilizzare (<**>) . pure direttamente nel codice.

+2

Con le leggi applicative, '((<**>). Puro) yu == u <*> puri == y puro ($ y) <*> u == FMAP ($ y) u' per tutti' Applicative's, ma il l'ultimo è solo più generale. –

Problemi correlati