From the link at book (here) you added, the type of seqn
is:
seqn :: Monad m -> [m a] -> m [a]
and it's implementation is:
seqn [] = return []
seqn (act:acts) = do
x <- act
xs <- seqn acts
return (x:xs)
And if you look at the type definition of sequenceA
:
sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)
is more general, since Monad is an applicative, and your implementation:
sequenceA [] = pure []
sequenceA (x:xs) = pure (:) <*> x <*> sequenceA xs
is essentially the same as seqn
edit:
To answer the question in the comments
I asked a new question to see the differences between one and another. Hope it helps:
Proving equality of functions from Applicative and Monad
to summarize
There is no do
notation for applicatives in Haskell, as you can read specifically in this segment.
This is a very nice article: Desugaring Haskell’s do-Notation into Applicative Operations, and its main idea is how to desugar the do
notation of monads into applicatives if you want to know.
return
and pure
do exactly the same, but with different constraints, right?, so this part pure (:)
and this part return (x:xs)
you can see that are covered.
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.
And that's what pure (:) <*> x <*> sequenceA xs
is essentially doing.