sono in grado di capire le basi di funzioni senza punto in Haskell:Capire `ap` in una funzione priva di punti in Haskell
addOne x = 1 + x
Come si vede x su entrambi i lati dell'equazione, semplifichiamo iT:
addOne = (+ 1)
Incredibilmente si scopre che funzioni in cui lo stesso argomento viene utilizzato due volte in diverse parti possono essere scritti senza punto!
Colgo come un esempio di base della funzione average
scritto come:
average xs = realToFrac (sum xs)/genericLength xs
può sembrare impossibile per semplificare xs
, ma http://pointfree.io/ se ne esce con:
average = ap ((/) . realToFrac . sum) genericLength
che funziona.
Per quanto ho capito questo afferma che average
è lo stesso di chiamare ap
su due funzioni, la composizione del (/) . realToFrac . sum
e genericLength
Purtroppo la funzione ap
ha alcun senso per me, la documentazione http://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Monad.html#v:ap Stato:
ap :: Monad m => m (a -> b) -> m a -> m b
In many situations, the liftM operations can be replaced by uses of ap,
which promotes function application.
return f `ap` x1 `ap` ... `ap` xn
is equivalent to
liftMn f x1 x2 ... xn
Ma la scrittura:
let average = liftM2 ((/) . realToFrac . sum) genericLength
non funziona, (dà un messaggio di errore di tipo molto lungo, chiedi e lo includerò), quindi non capisco cosa stanno cercando di dire i documenti.
Come funziona l'espressione ap ((/) . realToFrac . sum) genericLength
? Potresti spiegare ap
in termini più semplici dei documenti?
'let average = liftM2 ((/). RealToFrac) somma genericLength' funziona. –
@ ØrjanJohansen Interessante, potresti spiegare perché in una risposta? – Caridorc
Dai un'occhiata all'implementazione di 'ap' dell'istanza Monad per le funzioni – Bergi