Possiamo fare un piccolo ragionamento equo. Diamo prima un'occhiata a bar'
. Scriverò in questa forma
asks bar >>= \z -> return (z i)
Si scopre che liftM
è definito per essere liftM f m = m >>= \a -> return (f a)
che si inserisce il modello di cui sopra. Quindi cerchiamo di sostituirlo con
liftM ($ i) (asks bar)
allora abbiamo foo
come
liftM show (liftM ($ i) (asks bar))
Oppure, scritto fuori un po 'particolare
liftM show . liftM ($ i) $ asks bar
Se sappiamo che liftM
è fmap
potremmo riconoscere la Functor
legge in gioco qui
fmap show . fmap ($ i) $ asks bar -- equals
fmap (show . ($ i)) $ asks bar
Io non sono personalmente un grande fan di utilizzare ($ i)
in funzione, quindi cerchiamo di riscrivere come un lambda esplicito
fmap (\f -> show (f i)) (asks bar)
Ora, potremmo decidere di eliminare la asks
utilizzando bar
presso il sito di chiamata (vale a dire utilizzare bar
in funzione del tipo di bar :: FooEnv -> Int -> Int
fmap (\f -> show (bar f i)) ask
e come un trucco finale, potremmo usare flip
andare inutile nella funzione fmap
ped e anche tornare l'uso di asks
(grazie Ørjan Johansen)
fmap (show . flip bar i) ask -- or even
show . flip bar i <$> ask -- or even
asks (show . flip bar i)
Non sto dicendo che questo è il modo più leggibile o più meraviglioso per eseguire questo compito, ma puoi vedere come possiamo ridurre i pezzi usando il ragionamento equo.
fonte
2014-09-08 04:30:58
Nota che 'chiede f' è equivalente a' f <$> ask', quindi dipende dai tuoi gusti, puoi reintrodurlo alla fine: 'chiede $ show. flip bar i' –
Grazie, @ j-abrahamson! I passaggi dettagliati sono molto utili. Avrei dovuto essere più specifico, però, nel senso che non voglio in linea "bar" in "foo". Lavorerò comunque per capire i passi che hai compiuto, così da poter provare a creare una versione point-free di "bar". Preferisco 'ask' a' ask', quindi grazie anche a @ Ørjan-johansen, per aver aggiunto il passaggio finale. – arussell84
L'ho capito: 'bar 'i' = chiede $ flip bar i'' o' bar '= ask. flip bar' – arussell84