[英]Proving equivalence of sequence definitions from Applicative and Monad
How can I properly prove that我怎样才能正确地证明这一点
sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)
sequenceA [] = pure []
sequenceA (x:xs) = pure (:) <*> x <*> sequenceA xs
is essentially the same to monad inputs as本质上与 monad 输入相同
sequenceA' :: Monad m => [m a] -> m [a]
sequenceA' [] = return []
sequenceA' (x:xs) = do
x' <- x
xs' <- sequenceA' xs
return (x':xs')
In spite of the constraint Applicative
and Monad
of course.当然,尽管有
Applicative
和Monad
的约束。
Here's a proof sketch:这是一个证明草图:
Show that显示
do x' <- x xs' <- sequenceA' xs return (x' : xs')
is equivalent to相当于
do f1 <- do cons <- return (:) x' <- x return (cons x') xs' <- sequenceA' xs return (f1 xs')
This involves desugaring (and resugaring) do
notation and applying the Monad laws .这涉及脱糖(和重新加糖)
do
符号和应用Monad 定律。
Use the definition of ap
:使用
ap
的定义:
ap m1 m2 = do { x1 <- m1; x2 <- m2; return (x1 x2) }
to turn the above code into把上面的代码变成
do f1 <- return (:) `ap` x xs' <- sequenceA' xs return (f1 xs')
and then进而
return (:) `ap` x `ap` sequenceA' xs
Now you have现在你有
sequenceA' [] = return [] sequenceA' (x:xs) = return (:) `ap` x `ap` sequenceA' xs
Assume that pure
and <*>
are essentially the same as return
and `ap`
, respectively, and you're done.假设
pure
和<*>
本质上分别与return
和`ap`
相同,那么您就完成了。
This latter property is also stated in the Applicative documentation : Applicative 文档中也说明了后一个属性:
If
f
is also aMonad
, it should satisfy如果
f
也是一个Monad
,它应该满足
pure = return
(<*>) = ap
Since the Functor-Applicative-Monad proposal , implemented in GHC 7.10, Applicative is a superclass of Monad.由于在 GHC 7.10 中实现的Functor-Applicative-Monad 提案,Applicative 是 Monad 的超类。 So even though your two functions can't be strictly equivalent, since
sequenceA
's domain includes sequenceA'
's domain, we can look at what happens in this common domain (the Monad
typeclass).因此,即使您的两个函数不能严格等效,因为
sequenceA
的域包括sequenceA'
' 的域,我们可以看看在这个公共域( Monad
类型类)中发生了什么。
This paper shows an interesting demonstration of desugaring do
notation to applicative and functor operations ( <$>
, pure
and <*>
).本文所示脱糖的一个有趣的演示
do
记号,以应用性和仿函数操作( <$>
pure
和<*>
If the expressions on the right hand side of your left-pointing arrows ( <-
) don't depend on each other, as is the case in your question, you can always use applicative operations, and therefore show that your hypothesis is correct (for the Monad
domain).如果你的左箭头 (
<-
) 右侧的表达式不相互依赖,就像你的问题一样,你总是可以使用应用运算,因此表明你的假设是正确的(对于Monad
域)。
Also have a look at the ApplicativeDo language extension proposal, which contains an example that's just like yours:另请查看ApplicativeDo语言扩展提案,其中包含一个与您类似的示例:
do
x <- a
y <- b
return (f x y)
which translates to:这意味着:
(\x y -> f x y) <$> a <*> b
Substituting f
for (:)
, we get:用
f
代替(:)
,我们得到:
do
x <- a
y <- b
return (x : y)
... which translates to... ......这翻译成......
(\x y -> x : y) <$> a <*> b
--And by eta reduction
(:) <$> a <*> b
--Which is equivalent to the code in your question (albeit more general):
pure (:) <*> a <*> b
Alternatively, you can make GHC's desugarer work for you by using the ApplicativeDo
language extension and by following this answer to the SO question "haskell - Desugaring do-notation for Monads".或者,您可以通过使用
ApplicativeDo
语言扩展并按照对 SO 问题“haskell - Desugaring do-notation for Monads”的回答来使 GHC 的 desugarer 为您工作。 I'll leave this exercise up to you (as it honestly goes beyond my capacities!).我会把这个练习留给你(因为它真的超出了我的能力!)。
My own two cents
我自己的两分钱
There is no do notation for applicatives in Haskell. Haskell 中没有应用程序的 do 符号。 It can be seen specifically in this segment .
可以在这部分具体看到。
return
and pure
do exactly the same, but with different constraints, right?, so this part pure (:)
and this part return (x:xs)
are essentially the same. return
和pure
完全一样,但有不同的约束,对吧?所以这部分pure (:)
和这部分return (x:xs)
本质上是一样的。
Then, here x <- act
you are getting the value of act, and then the value of the recursion xs <- seqn acts
, to finally wrap it with the return
.然后,在这里
x <- act
你得到的是 act 的值,然后是递归xs <- seqn acts
act 的值,最后用return
包裹它。
And that's what pure (:) <*> x <*> sequenceA xs
is essentially doing.这就是
pure (:) <*> x <*> sequenceA xs
本质上所做的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.