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.