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

From Programming in Haskell by Hutton

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

and is its implementation

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

What is the relation and difference between seqn and sequenceA?

Since a monad is an applicative, is seqn the sequenceA limited to monad?

developer_hatch
  • 15,898
  • 3
  • 42
  • 75
Tim
  • 1
  • 141
  • 372
  • 590
  • 3
    by `seqn` I assume you mean [sequence](https://hackage.haskell.org/package/base-4.12.0.0/docs/Prelude.html#v:sequence)? (I totally agree with @AJFarmar's comment too.) – Robin Zigmond Jul 28 '19 at 13:37
  • @RobinZigmond, I should note that `sequence` and `mapM` aren't entirely vestigial. The stream fusion system for `vector`, for example, allows a better implementation of `mapM` than of `traverse`. – dfeuer Jul 28 '19 at 16:20
  • the real question here it seems is, what exactly is `<*>` and how it can be related to the monadic `>>=`? of course this question only makes sense for types which have instances of both. in that case, `(<*>)` = [`ap`](https://hackage.haskell.org/package/base-4.12.0.0/docs/Control-Monad.html#v:ap) (look at their types, they are exactly the same if we swap `Applicative` and `Monad` in their constraint (that part of a type which looks like `Monad a => ...`)). and `ap` [is defined](https://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Base.html#liftM5) in terms of `do`, i.e. `>>=`. – Will Ness Jul 29 '19 at 05:54
  • `sequence` is *the* salient example with which `Applicative` was [originally introduced](http://strictlypositive.org/Idiom.pdf) / invented / discovered. you can search for "difference between Monad and Applicative" (here on SO, and elsewhere) for more context for this. here's [one example](https://stackoverflow.com/a/24467994/849891). – Will Ness Jul 29 '19 at 05:59
  • more about Monad / Applicative correspondence (a.o.t. difference) is e.g. [here](https://stackoverflow.com/a/22117522/849891). But some types allow for a more specialized (more efficient, perhaps) implementation of `<*>` a.o.t. just using `ap`. For such types, `sequence` and `sequenceA` are not necessarily exactly the same thing. Does that answer your question? – Will Ness Jul 29 '19 at 06:07
  • and check out [this answer](https://stackoverflow.com/a/57247698/849891)! – Will Ness Jul 29 '19 at 11:10

1 Answers1

2

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.

developer_hatch
  • 15,898
  • 3
  • 42
  • 75