AFAIK one of the new additions to GHC8 is the ApplicativeDo
language extension, which desugars the do-notation to the corresponding Applicative
methods (<$>
, <*>
) if possible. I have the following questions.
How does it decide whether the desugaring to Applicative
methods is possible? From what I know, it does a dependency check (if the later depends on the result of former) to decide the eligibility. Are there any other criteria?
Although this addition makes applicative code easier to read for classes that don't have any Monad instance (maybe ?). But for structures that both have a Monad and an Applicative instance: Is this a recommended practice (from the readability perspective)? Are there any other benefits?
Definition. In Haskell, an applicative is a parametrized type that we think of as being a container for data of that type plus two methods pure and <*> . Consider a parametrized type f a . The pure method for an applicative of type f has type. pure :: a -> f a.
Functor in Haskell is a kind of functional representation of different Types which can be mapped over. It is a high level concept of implementing polymorphism. According to Haskell developers, all the Types such as List, Map, Tree, etc. are the instance of the Haskell Functor.
They are equivalent, in practice.
What is a Monad? A monad is an algebraic structure in category theory, and in Haskell it is used to describe computations as sequences of steps, and to handle side effects such as state and IO. Monads are abstract, and they have many useful concrete instances. Monads provide a way to structure a program.
How does it decide whether the desugaring to
Applicative
methods is possible? From what I know, it does a dependency check (if the later depends on the result of former) to decide the eligibility. Are there any other criteria?
The paper and trac page are the best sources of information. Some points:
ApplicativeDo
uses applicatives wherever possible - including mixing them with >>=
in some cases where only part of the do
block is applicativeAlthough this addition makes applicative code easier to read for classes that don't have any
Monad
instance (maybe ?). But for structures that both have aMonad
and anApplicative
instance: Is this a recommended practice (from the readability perspective)? Are there any other benefits?
Here is an answer about the difference between Applicative
and Monad
. To quote directly:
To deploy
<*>
, you choose two computations, one of a function, the other of an argument, then their values are combined by application. To deploy>>=
, you choose one computation, and you explain how you will make use of its resulting values to choose the next computation. It is the difference between "batch mode" and "interactive" operation.
A prime example of this sort of thing is the Haxl
monad (designed by Facebook) which is all about fetching data from some external source. Using Applicative
, these requests can happen in parallel while Monad
forces the requests to be sequential. In fact, this example is what motivated Simon Marlow at Facebook to make the ApplicativeDo
extension in the first place and write the quoted paper about it.
In general, most Monad
instances don't necessarily benefit from Applicative
. From the same answer I quoted above:
I appreciate that
ApplicativeDo
is a great way to make more applicative (and in some cases that means faster) programs that were written in monadic style that you haven't the time to refactor. But otherwise, I'd argue applicative-when-you-can-but-monadic-when-you-must is also the better way to see what's going on.
So: use Applicative
over Monad
when possible, and exploit ApplicativeDo
when it really is nicer to write (like it must have been in some cases at Facebook) than the corresponding applicative expression.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With