Starting with scala monads. One can frequently run into situation of dealing with Monads of monad and requires it to convert into single monad for the ease of us. For example,
Set[IO[Either[A,B]] -> IO[Set[C]]
Though this can be achieved by converting into sequence and then map,
monadSet
.toList
.sequence[IO, Either[A,B]]
.map(...)
It gets complex when there is more than one,
Say IO[IO[Set[Either[A,B]]]] or Future[Set[Either[A, Future[B]]. How to handle these nested monads in general is not quite clear. Any resource on this would be helpful.
Edit: Nested monad of same type is not a problem usually. The main problem is nested monad of different types.
Thanks for the comments. Though in general monads don't compose, i find herding cats monad transformers solving the problem to an extent.
Especially EitherT and optionT wraps around the multiple monads and provides generic way of dealing with monads. They are just intuitive and this blog also helps in understanding the motivation behind it.
Related
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.
I'm currently porting some code from traditional Scala to Scalaz style.
It's fairly common through most of my code to use the Seq trait in my exposed API signatures rather than a concrete type (i.e. List, Vector) directly. However, this poses some problem with Scalaz, since it doesn't provide an implementation of a Bind[Seq] typeclass.
i.e. This will work correctly.
List(1,2,3,4) >>= bindOperation
But this will not
Seq(1,2,3,4) >>= bindOperation
failing with the error could not find implicit value for parameter F0: scalaz.Bind[Seq]
I assume this is an intentional design decision in Scalaz - however am unsure about intended/best practice on how to precede.
Should I instead write my code directly to List/Vector as appropriate instead of using the more flexible Seq interface? Or should I simply define my own Bind[Seq] typeclass?
The collections library does backflips to accommodate subtyping: when you use map on a specific collection type (list, map, etc.), you'll (usually) get the same type back. It manages this through the use of an extremely complex inheritance hierarchy together with type classes like CanBuildFrom. It gets the job done (at least arguably), but the complexity doesn't feel very principled. It's a mess. Lots of people hate it.
The complexity is generally pretty easy to avoid as a library user, but for a library designer it's a nightmare. If I provide a monad instance for Seq, that means all of my users' types get bumped up the hierarchy to Seq every type they use a monadic operation.
Scalaz folks tend not to like subtyping very much, anyway, so for the most part Scalaz stays around the leaves of the hierarchy—List, Vector, etc. You can see some discussion of this decision on the mailing list, for example.
When I first started using Scalaz I wrote a lot of utility code that tried to provide instances for Seq, etc. and make them usable with CanBuildFrom. Then I stopped, and now I tend to follow Scalaz in only ever using List, Vector, Map, and Set in my own code. If you're committed to "Scalaz style", you should do that as well (or even adopt Scalaz's own IList, ISet, ==>>, etc.). You're not going to find clear agreement on best practices more generally, though, and both approaches can be made to work, so you'll just need to experiment to find which you prefer.
I find myself writing my programs more and more in the style like this:
myList
.map(el => ...)
.filter(_....)
.map { el =>
...
...
}
.zipWithIndex
.foreach(println)
Often my subroutine consists entirely of such block of code. I never planned to change my style of coding into this, it just happened naturally as I used Scala more and more.
Is it correct to say that such code is written in "monadic style"? I do have a vague understanding of what a monad is, and I am using Scala's collections here, and those seem to be monadic types. On the other hand I am not creating any monadic types myself, I am just using them. In other words, when I want to say merely that I program in take_something.change_it.change_it.use_it style, is it ok to refer to it as "monadic style"?
I would say that programming that way is a consequence of using monads, but I'd only describe it as fully programming in monadic style if you're really relying on monads to program completely free of side-effects, using things like IO monads and State monads. You tend to end up with a whole bunch of nested (as opposed to chained) maps, flatMaps, and filters. The Scala for...yield construct helps organize code that works with multiple nested monads. You may find the book Functional Programming in Scala interesting, for really delving into that style.
Your example is certainly monadic in the smaller sense of using chained transformations on one monadic type. That pattern is used in a lot of code that I wouldn't necessarily describe as "monadic", and is sometimes called method cascading or the fluent pattern.
Option monad turns pretty much a facility some times in Scala. Are there any other monads in Scala standard library?
Luigi's answer is correct, but not very informative, IMHO.
All collections can implement the monad interface, but the signature for flatMap in them is not a monad's flatMap. They'll act like monads most of the time, though. Almost all of the classes listed by Luigi are related to collections.
LeftProject and RightProject refers to Either. Basically, Either is not a monad, but if you "project" one of the sides, then that side acts pretty much like an Option monad.
Parser is a monad, which forms the basis of parser combinators.
I admit I do not recognize ControlContext. I wonder if it is related to continuations (which are monads as well).
You can work this out by looking up the tell-tale flatMap in the API index. It gives:
FilterMonadic
Stream
StreamWithFilter
TraversableMethods
Iterator
ParIterableLike
ParIterableLike
ParIterableViewLike
TraversableLike
WithFilter
MonadOps
TraversableProxyLike
TraversableViewLike
LeftProjection
RightProjection
Option
WithFilter
Responder
Zipped
ControlContext
Parser
Here are the links to three sources files from Scalaz:
Pure.scala
Bind.scala
Monad.scala
Take a look at instance declarations. That might give you an idea about what types from the standard library satisfy the monadic interface.
I had some experience in Haskell and currently learning Scala. Am wondering whether there is something equivalent to Monads in Scala??
You probably want to check out scalaz; it's been strongly influenced by Haskell. Indeed, it has often been asked of one of the prime contributors why they aren't just using Haskell, as they seem to like it so much!
Scalaz makes heavy use of implicits in order to decorate structures with their monads. For example:
val fibs = (0, 1).iterate[Stream]( i => i._2 -> (i._2 + i._1) ).map(_._1)
println( fibs.take(10) )
I think is worth noting that Scala's "for-comprehension" is equivalent to Haskell's monadic "do"
Both Option and List are monads. I also believe that Either's left and right projections are also monads.
There is no explicit concept of monad in Scala standard library (there is no appropriate trait/class or typeclass).
Scala deals with this in kind of an ad-hoc manner, see Scala by example's section on for comprehensions for details.