2012-01-06 12 views
15

Penso di capire come funzionano i functor applicativi in ​​Haskell e li sto usando per i tipi di dati di base (Forse, O ...). Tuttavia, ho trovato this question con il seguente esempio:Quale funtore applicativo viene utilizzato per passare parametri condivisi?

withPool pool = bracket (takeConn pool) (putConn pool) 

può essere riscritta in stile applicativa:

withPool = bracket <$> takeConn <*> putConn 

mi ha sorpreso è stato compilato e in effetti funziona come previsto, ma potrebbe qualcuno mi che applicativo dire Per questo viene utilizzato Functor e come viene definito?

Aggiornamento: Penso di aver capito come funziona, ma non ho idea di dove sia definito.

risposta

17

Unificare f = (a ->) nelle firme di tipo:

fmap :: (b -> c) -> (a -> b) -> (a -> c) 
pure :: b -> (a -> b) 
(<*>) :: (a -> b -> c) -> (a -> b) -> (a -> c) 

L'unica ragione per cui le dichiarazioni sono sintatticamente diversi, ((->) a) vs (a ->), è che non ti è permesso di prendere le sezioni a livello tipo. Così si finisce con questi, dopo i tipi caccia:

instance Functor ((->) a) where 
    fmap = (.) 

instance Applicative ((->) a) where 
    pure = const 
    f <*> g = \x -> f x $ g x 

Sono abbastanza sicuro che l'istanza Functor è in Data.Functor, e l'istanza Applicative è in Control.Applicative. L'istanza Monad per ((->) a) è l'unica in uno strano punto, in Control.Monad.Instances, anziché Control.Monad. Almeno se ricordo correttamente.

+9

Per quello che vale, questo è in realtà il lettore monade, meno un wrapper 'newtype' - il" parametro condiviso "qui è lo stesso di" ambiente "per' Reader'. In modo simile, "err" è l'errore monade e "(,) w' è scrittore. –

+0

@ C.A.McCann Vale la pena segnalarlo, e mi sono dimenticato di farlo. Grazie per averlo aggiunto. – Carl

Problemi correlati