Estoy aprendiendo los aplicantes de Haskell. Me parece (probablemente estoy equivocado) que la pure
función no es realmente necesaria, por ejemplo:
pure (+) <*> [1,2,3] <*> [3,4,5]
Se puede escribir como
(+) <$> [1,2,3] <*> [3,4,5]
¿Alguien puede explicar el beneficio que pure
proporciona la función sobre el mapeo explícito fmap
?
haskell
applicative
Gil Shafriri
fuente
fuente
pure f <*> x
es exactamente lo mismo quefmap f x
. Estoy seguro de que hay alguna razón por la quepure
se incluyóApplicative
, pero no estoy completamente seguro de por qué.pure
permite usar, bueno, valores "puros" en un cálculo aplicativo. Si bien, como se observa correctamente,pure f <*> x
es el mismo quef <$> x
, no hay tal equivalente para, por ejemplo,f <*> x <*> pure y <*> z
. (Al menos no lo creo)Monoid
clase importante , en la quepure
corresponde alMonoid
elemento de identidad. (Esto sugiere queApplicative
sinpure
podría ser interesante, yaSemigroup
que, que es unMonoid
sin tener necesariamente una identidad, todavía se usa. En realidad, ahora que lo pienso, parece recordar que PureScript tiene exactamente esapure
clase de "Aplicativo sin ", aunque no no sé para qué se usa.)fmap (\f' x' z' -> f' x' y z') f <*> x <*> z
, creo. La idea está en laApplicative
documentación como la ley del "intercambio".Applicative
sinpure
existe a partirApply
de semigroupoids .Respuestas:
Estoy al borde de mi competencia aquí, así que no tome esto por más de lo que es, pero fue demasiado largo para un comentario.
Puede haber razones prácticas para incluir
pure
en la clase de tipo, pero muchas abstracciones de Haskell se derivan de fundamentos teóricos, y creo que ese es el casoApplicative
también. Como dice la documentación, es un functor monoidal fuerte y laxo (consulte https://cstheory.stackexchange.com/q/12412/56098 para obtener más detalles). Supongo quepure
sirve como identidad , al igual que loreturn
hace paraMonad
(que es un monoide en la categoría de endofunctores ).Considere
pure
yliftA2
:Si entrecierra un poco los ojos, puede imaginarse que
liftA2
es una operación binaria, que también es lo que dice la documentación:pure
, entonces, es la identidad correspondiente.fuente
Applicative
sinpure
sería un, hm, semigroupal functor en lugar de uno monoidal.fmap
no siempre lo corta Específicamente,pure
es lo que te permite introducirf
(dóndef
estáApplicative
) cuando aún no lo tienes. Un buen ejemplo esToma una lista de "acciones" que producen valores y la convierte en una acción que produce una lista de valores. ¿Qué sucede cuando no hay acciones en la lista? El único resultado sano es una acción que no produce valores:
Si no lo hubiera hecho
pure
, se vería obligado a requerir una lista de acciones no vacía. Definitivamente podría hacerlo funcionar, pero es como hablar de la suma sin mencionar 0 o la multiplicación sin 1 (como han dicho otros, porque losApplicative
s son monoidales). En repetidas ocasiones se encontrará con casos extremos que se resolverían fácilmentepure
pero que, en cambio, deben resolverse mediante restricciones extrañas en sus entradas y otras curitas.fuente