Ultimamente ho scritto codice FFI che restituisce una struttura dati nella monade IO. Per esempio:Ciò che è preferito tra liftM, lilftA, ecc.
peek p = Vec3 <$> (#peek aiVector3D, x) p
<*> (#peek aiVector3D, y) p
<*> (#peek aiVector3D, z) p
Ora mi viene in mente quattro modi piacevoli per scrivere che il codice, tutti strettamente correlati:
peek p = Vec3 <$> io1 <*> io2 <*> io3
peek p = liftA3 Vec3 io1 io2 io3
peek p = return Vec3 `ap` io1 `ap` io2 `ap` io3
peek p = liftM3 Vec3 io1 io2 io3
Si noti che sto chiedendo di codice monade che non richiede nulla al di là cosa fornisce Applicative
. Qual è il modo preferito per scrivere questo codice? Devo usare Applicative
per sottolineare cosa fa il codice, o dovrei usare Monad
perché potrebbe (?) Avere ottimizzazioni su Applicative
?
La domanda è un po 'complicata dal fatto che ci sono solo [liftA..liftA3]
e [liftM..liftM5]
ma ho diversi record con più di tre o cinque membri, quindi se decido di andare con lift{A,M}
ho perdere un po' di coerenza, perché avrei dovuto usare un metodo diverso per i record più grandi.
La coerenza indica "ap" o "<*>". Quale scegli tu sia in gran parte una questione di gusti. La mia preferenza (e ho l'impressione che non sia solo mia) è "<*>". –