Estou aprendendo os candidatos de Haskell. Parece-me (provavelmente estou errado) que a pure
função não é realmente necessária, por exemplo:
pure (+) <*> [1,2,3] <*> [3,4,5]
pode ser escrito como
(+) <$> [1,2,3] <*> [3,4,5]
Alguém pode explicar o benefício que a pure
função fornece sobre o mapeamento explícito fmap
?
haskell
applicative
Gil Shafriri
fonte
fonte
pure f <*> x
é exatamente o mesmo quefmap f x
. Estou certo de que há alguma razão pela qualpure
foi incluídoApplicative
, mas não sei por que.pure
permite usar, bem, valores "puros" em uma computação Aplicativa. Enquanto, como você observa corretamente,pure f <*> x
é o mesmo quef <$> x
, não existe um equivalente para, digamosf <*> x <*> pure y <*> z
,. (Pelo menos acho que não.)Monoid
classe importante - na qualpure
corresponde aoMonoid
elemento de identidade de. (Isso sugere queApplicative
sempure
poderia ser interessante, poisSemigroup
- que é umMonoid
sem necessariamente ter uma identidade - ainda é usado. Na verdade, agora penso nisso, me lembro que o PureScript tem exatamente umapure
classe "Aplicativa sem ", embora eu não não sei para que serve.)fmap (\f' x' z' -> f' x' y z') f <*> x <*> z
, eu acho. A idéia está naApplicative
documentação como a lei do "intercâmbio".Applicative
sempure
existe a partirApply
de semigroupóides .Respostas:
Estou no limite da minha competência aqui, por isso não aceite isso por mais do que é, mas demorou um pouco demais para comentar.
Pode haver razões práticas para incluir
pure
na classe type, mas muitas abstrações de Haskell são derivadas de fundamentos teóricos, e acredito que esse seja o casoApplicative
também. Como a documentação diz, é um forte functor monoidal relaxado (consulte https://cstheory.stackexchange.com/q/12412/56098 para obter uma elaboração). Suponho que issopure
sirva como identidade , assim comoreturn
faz paraMonad
(que é um monóide na categoria de endofuncionadores ).Considere
pure
eliftA2
:Se você apertar os olhos um pouco, poderá imaginar que
liftA2
é uma operação binária, que também é o que a documentação afirma:pure
, então, é a identidade correspondente.fonte
Applicative
sempure
seria um, hm, functor semigroupal em vez de monoidal.fmap
nem sempre é fácil. Especificamente,pure
é o que permite apresentarf
(ondef
estáApplicative
) quando você ainda não o possui. Um bom exemplo éEle pega uma lista de "ações" que produzem valores e a transforma em uma ação que produz uma lista de valores. O que acontece quando não há ações na lista? O único resultado sensato é uma ação que não produz valores:
Se você não tivesse
pure
, seria obrigado a exigir uma lista não vazia de ações. Você definitivamente poderia fazê-lo funcionar, mas é como falar sobre adição sem mencionar 0 ou multiplicação sem 1 (como outros já disseram, porqueApplicative
s são monoidais). Você encontrará repetidamente casos extremos que seriam facilmente resolvidos,pure
mas que precisam ser resolvidos por restrições estranhas em suas entradas e outros band-aids.fonte