When to use monads from scalaz? - scala

I'd like to create a simple wrapper for computations. The built-in scala monads (TraversableLike) seems sufficient for me. And they have already syntax sugar. From some point of view scala collection traits are accidental monads. And there intended monads provided by the scalaz library.
What uses cases benefit from complex type classed monads of scalaz? What functionality is unfeasible for built-in monads and indicate need for scalaz?
Some clarification.
This question is not a holy war inheritance vs type classes. My question is about infrastructure that provides scalaz. Not any library with type classes approach, but this mentioned library. It slightly complicates things. But also it have bunch of utility classes that have no matches in scala collection library. Because it is a collection library, not a monadic. So the question is about the additional functionality provided by scalaz. In which cases does it matter?

First for a point about terminology: it's sometimes useful shorthand to say things like "Option is a monad", but "Option has a monad instance" or "Option is monadic" is clearer. It's potentially a little confusing to say that Scalaz provides a bunch of monads—what it provides is a Monad type class and instances of that type class for a number of types, including some of its own (e.g. \/, Task, etc.) and some from the standard library (List, Option, etc.).
So I'm going to answer a question which is similar to your question: what's the value of an explicit Monad type class over the monadic syntactic sugar provided by the standard library?
One place where having an explicit Monad representation is useful is when you want to define your own generic combinators or operations. Suppose I want to write a method addM that takes two monadic M[Int] values and adds them in the monad. It's easy to write for Option:
def addM(oa: Option[Int], ob: Option[Int]): Option[Int] = for {
a <- oa
b <- ob
} yield a + b
Or for lists:
def addM(oa: List[Int], ob: List[Int]): List[Int] = for {
a <- oa
b <- ob
} yield a + b
These two implementations obviously have a lot in common, and it'd be nice to be able to write a single generic implementation that would work in both cases—and for any other monadic type as well. This is really hard if we only have the standard library's hand-wavy monadic syntax, and really easy if we have a Monad type class.

Related

Why is Functor in scala cats required

I have just started to learn Scala cats framework. I am reading Functor. I understood its features but I don't understand it's usage. Why should I use it if there is a map method already available in Functors like List, Option etc.
As an example,
val list = List(1, 2, 3)
Functor[List].map(list)(x => x * 2)
But the same can be achieved with
list.map(x => x * 2)
What do we get when we abstract the method map inside Functor trait.
Can someone please throw some light on it so that I understand its usage.
You can call .map on object, when you know that this object has this method, and that this method is called this way. If you know exact type of the object, then compiler can check that, indeed, this is the case. But what if you don't know the type of the object? And what if you don't want to use runtime reflection?
Imagine situation like this:
def doubleIntInF[F[_]: Functor](fInt: F[Int]): F[Int] =
fInt.map(_ * 2)
Here, we don't know the type of F - it might be List, Option, Future, IO, Either[String, *]. And yet we are able to .map over it without using reflection - we use Functor[F] to power extension methods. We could do it also without extension method like this:
def doubleIntInF[F[_]: Functor](fInt: F[Int]): F[Int] =
Functor[F].map(fInt)(_ * 2)
and it would work (as long as we have the right implicits in scope):
doubleIntInF(List(1,2,3,4,5,6)) // List(2, 4, 6, 8, 10, 12
doubleIntInF(Option(4)) // Some(2)
In cases, where we know, that F=List, Option, etc - we have no reason to use it. But we have all the reasons to use if this F is dynamic.
And why would we like to make this F dynamic? To use it in libraries which e.g. could combine several functionalities provided through type classes together.
E.g. if you have F[_] and G[_] and you have Traverse[F] and Applicative[G] (more powerful Functor) you are able to turn F[G[A]] into G[F[A]]:
val listOption: List[Option] = List(Some(1), Some(2))
listOption.sequence // Some(List(1, 2))
val listFuture: List[Option] = List(Future(1), Future(2))
listFuture.sequence // Future(List(1, 2))
Virtually all libraries in Cats ecosystem use this concept (called typeclasses) to implement functionality without assuming that you pick the same data structures and IO components as they would. As long as you can provide typeclass instances that proves that they can safely use some methods on your type, they can implement the functionality (e.g. Cats Effect are extending Cats with some typeclasses and Doobie, FS2, Http4s, and so on build on top of these without making assumption about what you use to run your computations).
So long story short - in cases like your it doesn't make sense to use Functor, but in general they enable you to still use .map in situations which are NOT as simple and you don't have a hardcoded type.
The question is similar to why in OOP someone needs an interface (trait) while its implementations have the same methods.
Interface is an abstraction. Abstractions are useful. While programming we prefer to focus on significant things and ignore details that are currently not significant. Also programming with interfaces helps to decouple entities creating better architecture.
Interfaces (like Comparable, Iterable, Serializable etc.) is the way to describe behavior in OOP. Type classes (like Functor, Monad, Show, Read etc.) is the way to describe behavior in FP.
If you just want to map (or flatMap) over a list (or an Option) you don't need Functor. If you want to work with all mappable things you need Functor, if you want to work with all flatMappable things you need Monad etc.

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.

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).

Understanding Gen.unit(x)

Working through Functional Programming in Scala, the book shows the Gen Monad definition. Gen, as I understand, is a ScalaCheck trait.
val genMonad = new Monad[Gen] {
def unit[A](a => A): Gen[A] = Gen.unit(a)
def flatMap[A, B](ma: Gen[A])(f: A => Gen[B]) =
ma.flatMap(f)
}
I believe that OptionMonad.unit is defined as Some(a), but I don't understand Gen.unit(a).
How is Gen.unit(a) defined?
A Gen[A] is just an object which can be repeatedly called to give instances of type A. These "generators" are used to drive the ScalaCheck automated testing framework, which lets programmers specify properties of objects of a given type, and then repeatedly generates instances of that type and checks those properties. Gen forms a monad, which is to say it supports the operations of "unit" and "bind", about which approximately a zillion tutorials can be found on the internet. Scala's idioms for monads are a bit inconsistent, as monad types have a standard method of bind, called flatMap, but none for unit. This is because Scala is object oriented, and unit doesn't take an object of it's monad, but instead returns one, so it doesn't make any sense to make unit a method of the underlying class. Instead, most Scala monads leave the unit method implicit, often as a single-element constructor of the monad type.
So with that background out of the way, what's unit of Gen[A]. Well it needs to be something which takes an object of type A as an argument, and then allows repeated generation of objects of type A. Since A could literally be anything, there's really only one thing we can come up with which fits this bill. unit(a) must be a boring generator which repeatedly returns a . Simple once you think it through.

What are practical uses of applicative style?

I am a Scala programmer, learning Haskell now. It's easy to find practical use cases and real world examples for OO concepts, such as decorators, strategy pattern etc. Books and interwebs are filled with it.
I came to the realization that this somehow is not the case for functional concepts. Case in point: applicatives.
I am struggling to find practical use cases for applicatives. Almost all of the tutorials and books I have come across so far provide the examples of [] and Maybe. I expected applicatives to be more applicable than that, seeing all the attention they get in the FP community.
I think I understand the conceptual basis for applicatives (maybe I am wrong), and I have waited long for my moment of enlightenment. But it doesn't seem to be happening. Never while programming, have I had a moment when I would shout with a joy, "Eureka! I can use applicative here!" (except again, for [] and Maybe).
Can someone please guide me how applicatives can be used in a day-to-day programming? How do I start spotting the pattern? Thanks!
Applicatives are great when you've got a plain old function of several variables, and you have the arguments but they're wrapped up in some kind of context. For instance, you have the plain old concatenate function (++) but you want to apply it to 2 strings which were acquired through I/O. Then the fact that IO is an applicative functor comes to the rescue:
Prelude Control.Applicative> (++) <$> getLine <*> getLine
hi
there
"hithere"
Even though you explicitly asked for non-Maybe examples, it seems like a great use case to me, so I'll give an example. You have a regular function of several variables, but you don't know if you have all the values you need (some of them may have failed to compute, yielding Nothing). So essentially because you have "partial values", you want to turn your function into a partial function, which is undefined if any of its inputs is undefined. Then
Prelude Control.Applicative> (+) <$> Just 3 <*> Just 5
Just 8
but
Prelude Control.Applicative> (+) <$> Just 3 <*> Nothing
Nothing
which is exactly what you want.
The basic idea is that you're "lifting" a regular function into a context where it can be applied to as many arguments as you like. The extra power of Applicative over just a basic Functor is that it can lift functions of arbitrary arity, whereas fmap can only lift a unary function.
Since many applicatives are also monads, I feel there's really two sides to this question.
Why would I want to use the applicative interface instead of the monadic one when both are available?
This is mostly a matter of style. Although monads have the syntactic sugar of do-notation, using applicative style frequently leads to more compact code.
In this example, we have a type Foo and we want to construct random values of this type. Using the monad instance for IO, we might write
data Foo = Foo Int Double
randomFoo = do
x <- randomIO
y <- randomIO
return $ Foo x y
The applicative variant is quite a bit shorter.
randomFoo = Foo <$> randomIO <*> randomIO
Of course, we could use liftM2 to get similar brevity, however the applicative style is neater than having to rely on arity-specific lifting functions.
In practice, I mostly find myself using applicatives much in the same way like I use point-free style: To avoid naming intermediate values when an operation is more clearly expressed as a composition of other operations.
Why would I want to use an applicative that is not a monad?
Since applicatives are more restricted than monads, this means that you can extract more useful static information about them.
An example of this is applicative parsers. Whereas monadic parsers support sequential composition using (>>=) :: Monad m => m a -> (a -> m b) -> m b, applicative parsers only use (<*>) :: Applicative f => f (a -> b) -> f a -> f b. The types make the difference obvious: In monadic parsers the grammar can change depending on the input, whereas in an applicative parser the grammar is fixed.
By limiting the interface in this way, we can for example determine whether a parser will accept the empty string without running it. We can also determine the first and follow sets, which can be used for optimization, or, as I've been playing with recently, constructing parsers that support better error recovery.
I think of Functor, Applicative and Monad as design patterns.
Imagine you want to write a Future[T] class. That is, a class that holds values that are to be calculated.
In a Java mindset, you might create it like
trait Future[T] {
def get: T
}
Where 'get' blocks until the value is available.
You might realize this, and rewrite it to take a callback:
trait Future[T] {
def foreach(f: T => Unit): Unit
}
But then what happens if there are two uses for the future? It means you need to keep a list of callbacks. Also, what happens if a method receives a Future[Int] and needs to return a calculation based on the Int inside? Or what do you do if you have two futures and you need to calculate something based on the values they will provide?
But if you know of FP concepts, you know that instead of working directly on T, you can manipulate the Future instance.
trait Future[T] {
def map[U](f: T => U): Future[U]
}
Now your application changes so that each time you need to work on the contained value, you just return a new Future.
Once you start in this path, you can't stop there. You realize that in order to manipulate two futures, you just need to model as an applicative, in order to create futures, you need a monad definition for future, etc.
UPDATE: As suggested by #Eric, I've written a blog post: http://www.tikalk.com/incubator/blog/functional-programming-scala-rest-us
I finally understood how applicatives can help in day-to-day programming with that presentation:
https://web.archive.org/web/20100818221025/http://applicative-errors-scala.googlecode.com/svn/artifacts/0.6/chunk-html/index.html
The autor shows how applicatives can help for combining validations and handling failures.
The presentation is in Scala, but the author also provides the full code example for Haskell, Java and C#.
Warning: my answer is rather preachy/apologetic. So sue me.
Well, how often in your day-to-day Haskell programming do you create new data types? Sounds like you want to know when to make your own Applicative instance, and in all honesty unless you are rolling your own parser, you probably won't need to do it very much. Using applicative instances, on the other hand, you should learn to do frequently.
Applicative is not a "design pattern" like decorators or strategies. It is an abstraction, which makes it much more pervasive and generally useful, but much less tangible. The reason you have a hard time finding "practical uses" is because the example uses for it are almost too simple. You use decorators to put scrollbars on windows. You use strategies to unify the interface for both aggressive and defensive moves for your chess bot. But what are applicatives for? Well, they're a lot more generalized, so it's hard to say what they are for, and that's OK. Applicatives are handy as parsing combinators; the Yesod web framework uses Applicative to help set up and extract information from forms. If you look, you'll find a million and one uses for Applicative; it's all over the place. But since it's so abstract, you just need to get the feel for it in order to recognize the many places where it can help make your life easier.
I think Applicatives ease the general usage of monadic code. How many times have you had the situation that you wanted to apply a function but the function was not monadic and the value you want to apply it to is monadic? For me: quite a lot of times!
Here is an example that I just wrote yesterday:
ghci> import Data.Time.Clock
ghci> import Data.Time.Calendar
ghci> getCurrentTime >>= return . toGregorian . utctDay
in comparison to this using Applicative:
ghci> import Control.Applicative
ghci> toGregorian . utctDay <$> getCurrentTime
This form looks "more natural" (at least to my eyes :)
Coming at Applicative from "Functor" it generalizes "fmap" to easily express acting on several arguments (liftA2) or a sequence of arguments (using <*>).
Coming at Applicative from "Monad" it does not let the computation depend on the value that is computed. Specifically you cannot pattern match and branch on a returned value, typically all you can do is pass it to another constructor or function.
Thus I see Applicative as sandwiched in between Functor and Monad. Recognizing when you are not branching on the values from a monadic computation is one way to see when to switch to Applicative.
Here is an example taken from the aeson package:
data Coord = Coord { x :: Double, y :: Double }
instance FromJSON Coord where
parseJSON (Object v) =
Coord <$>
v .: "x" <*>
v .: "y"
There are some ADTs like ZipList that can have applicative instances, but not monadic instances. This was a very helpful example for me when understanding the difference between applicatives and monads. Since so many applicatives are also monads, it's easy to not see the difference between the two without a concrete example like ZipList.
I think it might be worthwhile to browse the sources of packages on Hackage, and see first-handedly how applicative functors and the like are used in existing Haskell code.
I described an example of practical use of the applicative functor in a discussion, which I quote below.
Note the code examples are pseudo-code for my hypothetical language which would hide the type classes in a conceptual form of subtyping, so if you see a method call for apply just translate into your type class model, e.g. <*> in Scalaz or Haskell.
If we mark elements of an array or hashmap with null or none to
indicate their index or key is valid yet valueless, the Applicative
enables without any boilerplate skipping the valueless elements while
applying operations to the elements that have a value. And more
importantly it can automatically handle any Wrapped semantics that
are unknown a priori, i.e. operations on T over
Hashmap[Wrapped[T]] (any over any level of composition, e.g. Hashmap[Wrapped[Wrapped2[T]]] because applicative is composable but monad is not).
I can already picture how it will make my code easier to
understand. I can focus on the semantics, not on all the
cruft to get me there and my semantics will be open under extension of
Wrapped whereas all your example code isn’t.
Significantly, I forgot to point out before that your prior examples
do not emulate the return value of the Applicative, which will be a
List, not a Nullable, Option, or Maybe. So even my attempts to
repair your examples were not emulating Applicative.apply.
Remember the functionToApply is the input to the
Applicative.apply, so the container maintains control.
list1.apply( list2.apply( ... listN.apply( List.lift(functionToApply) ) ... ) )
Equivalently.
list1.apply( list2.apply( ... listN.map(functionToApply) ... ) )
And my proposed syntactical sugar which the compiler would translate
to the above.
funcToApply(list1, list2, ... list N)
It is useful to read that interactive discussion, because I can't copy it all here. I expect that url to not break, given who the owner of that blog is. For example, I quote from further down the discussion.
the conflation of out-of-statement control flow with assignment is probably not desired by most programmers
Applicative.apply is for generalizing the partial application of functions to parameterized types (a.k.a. generics) at any level of nesting (composition) of the type parameter. This is all about making more generalized composition possible. The generality can’t be accomplished by pulling it outside the completed evaluation (i.e. return value) of the function, analogous to the onion can’t be peeled from the inside-out.
Thus it isn’t conflation, it is a new degree-of-freedom that is not currently available to you. Per our discussion up thread, this is why you must throw exceptions or stored them in a global variable, because your language doesn’t have this degree-of-freedom. And that is not the only application of these category theory functors (expounded in my comment in moderator queue).
I provided a link to an example abstracting validation in Scala, F#, and C#, which is currently stuck in moderator queue. Compare the obnoxious C# version of the code. And the reason is because the C# is not generalized. I intuitively expect that C# case-specific boilerplate will explode geometrically as the program grows.