este problema se puede abordar de diferentes formas, sin embargo te dejamos la solución más completa para nosotros.
Solución:
<*> :: Applicative f => f (a -> b) -> f a -> f b
es el aplicación secuencial función que trabaja en un Applicative
estructura. Para una función, esto se implementa como [src]:
instance Applicative ((->) r) where pure = const (<*>) f g x = f x (g x) liftA2 q f g x = q (f x) (g x)
asi que f <*> g
es corto para x -> f x (g x)
. Esto significa, por tanto, que en el caso de avg
:
avg = div . sum <*> length
es equivalente a:
avg x = (div . sum) x (length x)
que es por lo tanto equivalente a:
avg x = div (sum x) (length x)
por lo que divide el sum x
con length x
.
No soy fanático de este truco en particular. utiliza el Applicative (a->)
instancia como un “fanout”, para pasar el argumento a dos funciones separadas. Esencialmente esas dos funciones son sum
y length
y los resultados se combinan de nuevo por div
que se puede expresar muy bien con combinadores de flechas (aunque un poco más detallado, porque las flechas realmente no se reproducen en el estilo curry predeterminado de Haskell):
import Control.Arrow
avg = uncurry div . (sum &&& length)
En el truco aplicativo, fusionas la función de combinación con la primera que comparte argumentos. Asi que div . sum
en este caso, y el resultado de la otra función length
luego se pasa al segundo argumento de la primera función.
También puedes usar
avg = liftA2 div sum length
que utiliza el Applicative
instancia también.
valoraciones y comentarios
Si para ti ha resultado de ayuda nuestro post, agradeceríamos que lo compartas con el resto seniors y nos ayudes a dar difusión a esta información.