Why do we need Monad Transformers in Scala? - scala

My understanding is the following:
Suppose M1 and M2 are monads, i.e. they provide functions unit and flatMap that comply to the monadic laws. Unfortunately we cannot create unit and flatMap for M1[M2] . It looks like the unit and flatMap don't always exist for any M1 and M2. I do not know if we need to prove it.
So the solution is to create a wrapper W for M1[M2], so that W[M1, M2] is a monad, and use it instead. This wrapper W is called Monad Transformer.
Do I understand it correctly ?

You are right. Typically they are used in for-comprehension constructions where you need to combine monads properties.
Monad transformers "step-by-step" here.

Related

Option is both a functor and a monad?

Is Scala's Option both a monad and a functor?
As I understand it, functor is just a data type that exposes the following API:
Functor:
wrap (or apply) which takes a primitive and wraps it inside the functor
map which takes a functor, unwraps it, applies some function and re-wraps it
So Option is a functor. Because I can apply an Option to a primitive giving me Option[T]. I can also map on Option to obtain what's inside the functor and repackage inside Option.
How is monad different? I had thought that a monad also had an apply function and a map function. From this article I gather that a monad also has flatMap? Which is defined as simply map but without repackaging the result inside a monad? (Or is it map without repacking the result inside a functor?!)
Since Option supplies both map and flatMap does that mean that Option is both a functor and a monad?
Short answer: Yes.
Longer answer: Every monad is an applicative functor and every applicative functor is a functor. In Object-Oriented terms: Monad <: Applicative <: Functor.

Application of understanding monad in real world

I'm studying functional programming in Scala and I learnt term monad. In short monad is:
trait M[A] {
def flatMap[B](f: A => M[B]): M[B]
}
def unit[A](x: A): M[A]
I know monad is just a concept based on above 2 rules. And we can meet many monads in real world such as List, Future ....
The only one problem I don't know is: why should we know term "monad" as comparing to understanding List apis, Future apis or anything apis ... Is understanding monad help us write better code or can design better functional code structure.
Thanks
Because Monad already is a known term in category theory. There are also 3 very important Monad laws, that a Monad has to adhere to.
In theory, we could call Monads whatever we'd like, i.e. "FlatMappable" or "Bindable", but the name "Monad" is already an established term in the functional programming community and is deeply linked to the Monad laws.
As to why you should learn to appreciate Monads over learning each api individually, it's all about abstraction and reuse of knowledge. Oftentimes when we look at a new concept we compare them to concepts we already know.
If you already understand the Future Monad, understanding the Task Monad will be much easier.
It's also good to mention, that for-comprehensions in Scala work exclusively on Monads. In fact for-comprehensions are just syntactic sugar for flatMap and map (there's also filter, but that's not incredibly relevant to Monads). So recognizing if something is a Monad instance, enables you to utilize this extra piece of syntactic sugar.
Also once you fully grasp the abstraction you can make use of concepts like Monad transformers, where the actual type of the Monad is less important.
Lastly, here are the Monad laws for completeness sake:
Left identity: M[F].pure(x).flatMap(f) == f(x)
Right identity: m.flatMap(pure(_)) == m
Associativity: m.flatMap(f).flatMap(g) == m.flatMap(x => f(x).flatMap(g))
About Monad API vs concrete APIs:
An example could be Free Monad pattern. It essentialy uses (at least) two monads: first one is wrapping your DSL's expressions, and the second one is effect monad, that is, modality that you interpret your expressions in (Option corresponds to something that could fail, Future also adds latency etc).
To be more concrete: consider a task where you have some latency, and you decide to use Futures. How will you unit test that? Return some futures and then use Await? Apart from adding unnecessary complexity, you can run into some problems with that. And you won't actually need to use Futures for some tests. The answer is to parametrize methods that are supposed to use Futures with Monad, so you can just use Identity monad, or Option, and just forget about aforementioned problem.

Monad Transformers in Scala

I have been trying simple Monad Transformers where I have for comprehensions involving M[F[A]] where M and F are monads. How can I make M[F[A]] and M[S[A]] work together in a for comp if S is a different monad?
For example:
val a: Future[List[Int]] = ...
val b: Future[Option[Int]] = ...
a requires a ListT[Future, Int] and b requires an OptionT[Future, Int] but these do not compose, do I need to use another transformer? Would this depend on the order I use them in the for comp?
Monad Transformers help you in composing two values of type F[G[X]].
In other terms, monad transformers work with F[G[X]] because they leverage the fact that you know how to compose two G[X] if Monad[G] exists.
Now, in case of F[G[X] and F[H[X]], even if you state that G and H have Monad instances, you still don't have a general way of composing them.
I'm afraid composing F[G[X]] and F[H[X]] has no general solution with monad transformers.
You could try using a monad transformer stack ListT[OptionT[Future, Int]] which combines all effects at once. You can lift a and b into values of that monad transformer stack.

What exactly makes Option a monad in Scala?

I know what the monads are and how to use them. What I don't understand is what makes, let's say, Option a monad?
In Haskell a monad Maybe is a monad because it's instantiated from Monad class (which has at least 2 necessary functions return and bind that makes class Monad, indeed, a monad).
But in Scala we've got this:
sealed abstract class Option[+A] extends Product with Serializable { ... }
trait Product extends Any with Equals { ... }
Nothing related to a monad.
If I create my own class in Scala, will it be a monad by default? Why not?
Monad is a concept, an abstract interface if you will, that simply defines a way of composing data.
Option supports composition via flatMap, and that's pretty much everything that is needed to wear the "monad badge".
From a theoretical point of view, it should also:
support a unit operation (return, in Haskell terms) to create a monad out of a bare value, which in case of Option is the Some constructor
respect the monadic laws
but this is not strictly enforced by Scala.
Monads in scala are a much looser concept that in Haskell, and the approach is more practical.
The only thing monads are relevant for, from a language perspective, is the ability of being used in a for-comprehension.
flatMap is a basic requirement, and you can optionally provide map, withFilter and foreach.
However, there's no such thing as strict conformance to a Monad typeclass, like in Haskell.
Here's an example: let's define our own monad.
class MyMonad[A](value: A) {
def map[B](f: A => B) = new MyMonad(f(value))
def flatMap[B](f: A => MyMonad[B]) = f(value)
override def toString = value.toString
}
As you see, we're only implementing map and flatMap (well, and toString as a commodity).
Congratulations, we have a monad! Let's try it out:
scala> for {
a <- new MyMonad(2)
b <- new MyMonad(3)
} yield a + b
// res1: MyMonad[Int] = 5
Nice! We are not doing any filtering, so we don't need to implement withFilter. Also since we're yielding a value, we don't need foreach either. Basically you implement whatever you wish to support, without strict requirements. If you try to filter in a for-comprehension and you haven't implemented withFilter, you'll simply get a compile-time error.
Anything that (partially) implements, through duck-typing, the FilterMonadic trait is considered to be a monad in Scala. This is different than how monads are represented in Haskell, or the Monad typeclass in scalaz. However, in order to benefit of the for comprehension syntactic sugar in Scala, an object has to expose some of the methods defined in the FilterMonadic trait.
Also, in Scala, the equivalent of the Haskell return function is the yield keyword used for producing values out of a for comprehension. The desugaring of yield is a call to the map method of the "monad".
The way I'd put it is that there's an emerging distinction between monads as a design pattern vs. a first-class abstraction. Haskell has the latter, in the form of the Monad type class. But if you have a type that has (or can implement) the monadic operations and obeys the laws, that's a monad as well.
These days you can see monads as a design pattern in Java 8's libraries. The Optional and Stream types in Java 8 come with a static of method that corresponds to Haskell return, and a flatMap method. There is however no Monad type.
Somewhere in between you also have the "duck-typed" approach, as Ionuț G. Stan's answer calls out. C# has this as well—LINQ syntax isn't tied to a specific type, but rather it can be used with any class that implements certain methods.
Scala, per se, does not provide the notion of a monad. You can express a monad as a typeclass but Scala also doesn't provide the notion of a typeclass. But Cats does. So you can create a Monad in Scala with the necessary boiler plate, e.g. traits and implicits cleverly used, or you can use cats which provides a monad trait out of the box. As a comparison, Haskel provides monads as part of the language. Regarding your specific question, an Option can be represented as a monad because it has a flatMap method and a unit method (wrapping a value in a Some or a Future, for example).

Scala equivalent to Haskell's sequence

Is there a Scala Library method that performs the conversion Seq[Option[T]] -> Option[Seq[T]]?
The Haskell equivalent would be sequence :: Monad m => [m a] -> m [a].
This is unfortunately not available in the standard library (although there is a Future.sequence, as pedrofurla points out above). Part of the reason for this is probably just that the Scala standard library doesn't have any idea about applicative functors (or even monads, really).
As pedrofurla also mentions above, Scalaz does provide sequence, and it's actually a lot more appropriately typed than Haskell's—instead of requiring something monadic inside a list as input, it accepts anything with an applicative functor instance inside something with a traversable instance (i.e., it's equivalent to Data.Traversable's sequenceA in Haskell, not the sequence in the Prelude).