首页 > 解决方案 > `seqn` 和 `sequenceA` 之间的关系和区别是什么?

问题描述

sequenceA :: Applicative f => [f a] -> f [a]
sequenceA []     = pure []
sequenceA (x:xs) = pure (:) <*> x <*> sequenceA xs

来自Hutton 的 Haskell 编程

seqn :: Monad m => [m a] -> m [a]

并且是它的实现

seqn [] = return [] 
seqn (act:acts) = do x<- act 
                  xs <- seqn acts 
                  return (x:xs)

和 之间有什么关系和seqn区别sequenceA

既然单子是一个应用程序,seqn那么是否sequenceA仅限于单子?

标签: listhaskellmonadsapplicative

解决方案


从您添加的书(此处)的链接中,类型seqn为:

seqn :: Monad m -> [m a] -> m [a]

它的实现是:

seqn [] = return []
seqn (act:acts) = do 
                     x  <- act 
                     xs <- seqn acts
                     return (x:xs)

如果您查看 的类型定义sequenceA

sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)

更通用,因为 Monad 是一个应用程序,并且您的实现:

sequenceA []     = pure []
sequenceA (x:xs) = pure (:) <*> x <*> sequenceA xs

本质上是一样的seqn

编辑:

为了回答评论中的问题, 我提出了一个新问题,以了解彼此之间的差异。希望它有所帮助: 证明 Applicative 和 Monad 的函数相等

总结

doHaskell中没有应用程序的表示法,您可以在本段中专门阅读。这是一篇非常好的文章:Desugaring Haskell's do-Notation into Applicative Operations,它的主要思想是do如果你想知道如何将 monads 的符号去糖化为应用程序。 return并且pure做同样的事情,但是有不同的约束,对吧?所以你可以看到这部分pure (:)和这部分都被覆盖了。return (x:xs)然后,在这里x <- act你得到 的值act,然后是 recursion 的值xs <- seqn acts,最后用 return 包装它。

pure (:) <*> x <*> sequenceA xs就是本质上在做的事情。


推荐阅读