What is a monad-transformer as distinct from a monad? - scala

The question says it all, really. I know a (Scala) Monad looks like this:
trait Monad[M[_]] {
def pure[A](a : A) : M[A]
def bind[A, B](ma : M[A], f : A => M[B]) : M[B]
}
What does a Monad Transformer look like? And what are they used for?
EDIT. Consider the following REPL session: if a monad transformer somehow decorates a monad with reader capabilities (or vice versa)
Let's say I just want to use replicateM from Scalaz;
scala> import scalaz._; import Scalaz._
import scalaz._
import Scalaz._
scala> some(4).replicateM[List](2)
res20: Option[List[Int]] = Some(List(4, 4))
Now let's say, rather than having an Option[Int], I need to read an Int value from a File:
scala> val f = (_ : java.io.File) => some(1)
f: (java.io.File) => Option[Int] = <function1>
So, I can treat this reader, as if it was a Monad?
scala> ReaderT(f).replicateM[List](2)
<console>:16: error: value replicateM is not a member of scalaz.ReaderT[Option,java.io.File,Int]
ReaderT(f).replicateM[List](2)
^
Err, no.
Apologies if this all seems stupid, I'm just trying to understand what lovely goodness my wrapping the File => Option[Int] in a ReaderT can actually buy me.

Monad transformers are type functions that when applied to a monad type, generate a new monad, that combines the behavior of both components.
E.g. in the xmonad window manager, the computations run inside:
newtype X a = X (ReaderT XConf (StateT XState IO) a)
that is, a Reader composed with a State and an IO monad.
Reader gives access to read-only memory
State provides a form of read-write state
IO allows arbitrary external effects
Note that monad transforms are thus higher-rank types. They take a monadic type of kind (* -> *), and yield a new type of that kind.
As always, the Haskell wiki has some useful content:
Monad transformers
Monad transformers step by step: a tutorial.
Where it all began:
Functional Programming with Overloading and Higher-Order Polymorphism

Monad Transformers are used for combining / extending monads (add capabilities of one monad to another). E.g., ReaderT (Reader Transformer) enriches given monad M with Reader capabilities (transforms given monad into Reader retaining original features of M).
At the same time, Monad Transformers are normal monads that have bind, return, and other operations.
You can find examples of monad transformers in Scalaz - e.g., for Reader and State monads.

I don't think Reader is for reading values from a file. Pretty sure it's for reading values of configuration. I think of it as an alternative to global variables, statics, or dynamic/thread-local variables (called "special variables" in Common Lisp or sometimes fluide variables in Scheme with it's "fluid-let"). So, use Reader/ReaderT rather than access a global or dynamic variable and rather than pass parameters into each of your methods that may require access to some configuration option. This can be useful when some very deep piece of code suddenly requires access to a new configuration option. You can pass the option down from your main() function, sneakily access a global or use Reader/ReaderT.

Related

Why Semigroupal for types that have Monad instances don't combine?

I am trying wrap my head around Semigroupals in Cats. Following are statements from "Scala with Cats" by Underscore.
cats.Semigroupal is a type class that allows us to combine contexts
trait Semigroupal[F[_]] {
def product[A, B](fa: F[A], fb: F[B]): F[(A, B)]
}
The parameters fa and fb are independent of one another: we can compute them in either order before passing them to product. This is in contrast to flatMap, which imposes a strict order on its parameters.
So basically, we should be able to combine two Either contexts as well but that doesn't seem to work:
import cats.instances.either._
type ErrorOr[A] = Either[Vector[String], A]
Semigroupal[ErrorOr].product(Left(Vector("Error 1")), Left(Vector("Error 2")))
// res3: ErrorOr[Tuple2[Nothing, Nothing]] = Left(Vector("Error 1"))
If the USP of semigroupal is to eagerly execute independent operations, both eithers must be evaluated before being passed to product and yet we can't have a combined result.
We might expect product applied to Either to accumulate errors instead of fail fast. Again, perhaps surprisingly, we find that product implements the same fail‐fast behaviour as flatMap.
Isn't it contrary to the original premise of having an alternative approach to be able to combine any contexts of same type?
To ensure consistent semantics, Cats’ Monad (which extends Semigroupal) provides a standard definition of product in terms of map and flatMap.
Why implement product in terms of map and flatMap? What semantics are being referred to here?
So why bother with Semigroupal at all? The answer is that we can create useful data types that have instances of Semigroupal (and Applicative) but not Monad. This frees us to implement product in different ways.
What does this even mean?
Unfortunately, the book doesn't covers these premises in detail! Neither can I find resources online. Could anyone please explain this? TIA.
So basically, we should be able to combine two Either contexts as well but that doesn't seem to work:
It worked, as you can see the result is a valid result, it type checks.
Semigrupal just implies that given an F[A] and a F[B] it produces an F[(A, B)] it doesn't imply that it would be able to evaluate both independently or not; it may, but it may as well not. Contrary to Monad which does imply that it needs to evaluate F[A] before because to evaluate F[B] it needs the A
Isn't it contrary to the original premise of having an alternative approach to be able to combine any contexts of same type?
Is not really a different approach since Monad[F] <: Semigroupal[F], you can always call product on any Monad. Implementing a function in terms of Semigroupal just means that it is open to more types, but it doesn't change the behavior of each type.
Why implement product in terms of map and flatMap? What semantics are being referred to here?
TL;DR; consistency:
// https://github.com/typelevel/cats/blob/54b3c2a06ff4b31f3c5f84692b1a8a3fbe5ad310/laws/src/main/scala/cats/laws/FlatMapLaws.scala#L18
def flatMapConsistentApply[A, B](fa: F[A], fab: F[A => B]): IsEq[F[B]] =
fab.ap(fa) <-> fab.flatMap(f => fa.map(f))
The above laws implies that for any F[A] and for any F[A => B] as long as there exists a Monad (actually FlatMap) for F then, fab.ap(fa) is the same as fab.flatMap(f => fa.map(f))
Now, why? Multiple reasons:
The most common one is the principle of least surprise, if I have a bunch of eithers and I pass them to a generic function, no matter if it requires Monad or Applicative I expect it to fail fast, since that is the behavior of Either.
Liskov, suppose I have two functions f and g, f expects an Applicative and g a Monad, if g calls f under the hood I would expect calling both to return the same result.
Any Monad must be an Applicative, however an accumulating Applicative version of Either requires a Semigroup for the Left, whereas, the Monad instance doesn't require that.
What does this even mean?
It means that we may define another type (for example, Validated) that would only satisfy the Applicative laws but not the Monad laws, as such it can implement an accumulating version of ap
Bonus, since having this situation of having a type that is a Monad but could implement an Applicative that doesn't require sequencing, is so common. The cats maintainers created Parallel to represent that.
So instead of converting your Eithers into Validateds to combine them using mapN you can just use parMapN directly on the Eithers.

In functional programming terms, what do you call something with an orElse or other fallback method?

Using scala for reference, we see a fallback behavior (orElse) in several places such as PartialFunction, Option, and cats EitherOps.
This feels similar to but not the same as the flattening behavior of a monad. Is there a functional programming term for things that exhibit this behavior?
Edit:
Some good answers so far, digging around more in cats, I've found
Semigroup[Option[String]].combine(None, Some("b"))
res0: Option[String] = Some(b)
Semigroup[Option[String]].combine(Some("a"), Some("b"))
res1: Option[String] = Some(ab)
SemigroupK[Option].combineK(None, Some("b"))
res2: Option[String] = Some(b)
SemigroupK[Option].combineK(Some("a"), Some("b"))
res3: Option[String] = Some(a)
SemigroupK[List].combineK(List("a"), List("b"))
res4: List[String] = List(a, b)
Alternative[List].unite(List(None, Some("a"), Some("b")))
res4: List[String] = List(a, b)
So I see now that the scalaz Alt and haskell Alternative are not quite the same as the cats Alternative. The more interesting thing is the SemigroupK (called Plus in scalaz according to the cats documentation).
So could we say this behavior is exhibited by a type for which you cannot define a semigroup without also having a semigroup for its inner type (because then we might say the scalaz Alt and haskell Alternative are semigroups for such kinds)?
A decent chunk of Scala is inspired by similar concepts in Haskell. In this particular case, orElse is pretty close to the "alternative" operator <|> in the Alternative typeclass.
In Haskell, an Applicative is a Functor (read: it contains things and has some way of interacting with those things) which has some meaningful monoidal way of "combining" those things: <*>. We can think of <*> as being somewhat similar (although not identical) to Scala's andThen, in that it takes two "successful" computations and sequences them. Under this analogy, an Alternative is an Applicative that provides a way to "recover" from failure, so <|> is more or less Scala's orElse.
Since you mentioned monads, Applicative is a weakening of Monad, in the sense that every Monad is an Applicative but not every Applicative is necessarily Monad. For example, multidimensional arrays can easily be made into Applicative but cannot be made Monad.
So, to summarize, I believe the term you're looking for is "applicative functor with alternative capabilities", codified in Haskell by the Alternative typeclass. If you want to sound terribly arrogant, we can call it by its mathematically rigorous name: a strong lax monoidal functor backed by an additional monoidal structure. But that's just if we're showing off.
There is Alt:
https://github.com/scalaz/scalaz/blob/series/7.3.x/core/src/main/scala/scalaz/Alt.scala
Basically, orElse becomes alt:
def alt[A](a1: =>F[A], a2: =>F[A]): F[A].

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.

Reader monad in Scala: return, local, and sequence

I'm using the Reader monad in Scala as provided by the scalaz library. I'm familiar with this monad as defined in Haskell. The problem is that I cannot find the functions equivalent to return, local, and sequence (among others).
Currently I use constructs that I do not like since I'm repeating myself or making my code a bit obscure.
Regarding return, I'm currently using:
Reader{_ => someValue}
I'd rather just use a construct like unit(someValue), but I could not find anything on the internet. There are tutorials like this one that use the approach above, and which I consider not optimal.
Regarding local I also have to do something similar: instead of typing something like: local f myReader I have to unfold its definition:
Reader{env => myReader.run(f(env))
Finally, sequence is a bit closer to what I would expect (being a Haskell refugee doing Scala):
readers: List[Reader[Env, T]]
readerTs: Reader[Env, List[T]] = readers.sequenceU
My problem with this implementation is that, being relatively new to Scala, the type of sequenceU
final class TraverseOps[F[_],A] private[syntax](val self: F[A])(implicit val F: Traverse[F]) extends Ops[F[A]] {
//...
def sequenceU(implicit G: Unapply[Applicative, A]): G.M[F[G.A]]
appears like rather obscure, and seems like black magic. Ideally I would like to use a sequence operations on Monads.
Is there a better translation of these constructs to Scala available on scalaz or similar library? I'm not married to any Functional library for Scala, so any solution using other libraries will do, although I'd rather have an answer using scalaz, since I already implemented my code using it.
To make the things simpler, I fill in some types. Changing them to defs with generic types should still work.
Also I extracted the ReaderInt type, to avoid confusion with type lambdas.
return / pure / point
Scala does not have automatic typeclass resolution, so you need to provide them implicitly. For Kleisli (being a monad transformer for reader),
Kleisli[Id, ?, ?] is enough
implicit val KA = scalaz.Kleisli.kleisliIdApplicative[Int]
type ReaderInt[A] = Kleisli[Id.Id, Int, A]
val alwaysHello = KA.point("hello")
or with imported syntax:
import scalaz.syntax.applicative._
val alwaysHello = "hello".point[ReaderInt]
So as a general rule, you
1) import the applicative intance, which usually located in scalaz.std.something.somethingInstance
2) import scalaz.syntax.something._
3) then you can write x.point[F], where F is your applicative.
local
Not sure, that it answers your question, but Kleisli has a local method.
val f: String ⇒ Int = _.length
val alwaysEleven = alwaysHello local f
sequencing
The same way, you are free to choose to use syntax for or to specify type classes explicitly.
import scalaz.std.list.listInstance
val initial: List[ReaderInt[String]] = ???
val sequenced: ReaderInt[List[String]] = Traverse[List].sequence[ReaderInt, String](initial)
import scalaz.syntax.traverse._
val z = x.sequence[ReaderInt, String]
I prefer not to use sequenceU, which uses Unapply typelcass to infer the G type, because sometimes scala has troubles of figuring out the right one.
And I personally do not find it messy to put in some types myself.
It may worth to look into cats, though it does not have much yet.

Why do monads not compose in scala

Why do monads not compose when a Monad is an Applicative and an Applicative is a Functor. You see this inheritance chain in many articles on the web ( Which i have gone through ). But when Functors and Applicatives compose why do Monads break this ?
Can someone provide a simple example in scala which demonstrates this issue ? I know this is asked a lot but kind of hard to understand without a simple example.
First, let's start with a simple problem. Let's say, we need to get a sum of two integers, each wrapped in both Future and Option. Let's take cats library in order to resemble Haskell’s standard library definitions with Scala-syntax.
If we use monad approach (aka flatMap), we need:
both Future and Option should have Monad instances defined over them
we also need monadic transformer OptionT which will work only for Option (precisely F[Option[T]])
So, here is the code (let's forget about for-comprehension and lifting to make it simpler):
val fa = OptionT[Future, Int](Future(Some(1)))
val fb = OptionT[Future, Int](Future(Some(2)))
fa.flatMap(a => fb.map(b => a + b)) //note that a and b are already Int's not Future's
if you look at OptionT.flatMap sources:
def flatMap[B](f: A => OptionT[F, B])(implicit F: Monad[F]): OptionT[F, B] =
flatMapF(a => f(a).value)
def flatMapF[B](f: A => F[Option[B]])(implicit F: Monad[F]): OptionT[F, B] =
OptionT(F.flatMap(value)(_.fold(F.pure[Option[B]](None))(f)))
You'll notice that the code is pretty specific to Option's internal logic and structure (fold, None). Same problem for EitherT, StateT etc.
Important thing here is that there is no FutureT defined in cats, so you can compose Future[Option[T]], but can't do that with Option[Future[T]] (later I'll show that this problem is even more generic).
On the other hand, if you choose composition using Applicative, you'll have to meet only one requirement:
both Future and Option should have Applicative instances defined over them
You don't need any special transformers for Option, basically cats library provides Nested class that works for any Applicative (let's forget about applicative builder's sugar to simplify understanding):
val fa = Nested[Future, Option, Int](Future(Some(1)))
val fb = Nested[Future, Option, Int](Future(Some(1)))
fa.map(x => (y: Int) => y + x).ap(fb)
Let's swap Option and Future:
val fa = Nested[Option, Future, Int](Some(Future(1)))
val fb = Nested[Option, Future, Int](Some(Future(1)))
fa.map(x => (y: Int) => y + x).ap(fb)
Works!
So yes Monad is Applicative, Option[Future[T]] is still a monad (on Future[T] but not on T itself) but it allows you to operate only with Future[T] not T. In order to "merge" Option with Future layers - you have to define monadic transformer FutureT, in order to merge Future with Option - you have to define OptionT. And, OptionT is defined in cats/scalaz, but not FutureT.
In general (from here):
Unfortunately, our real goal, composition of monads, is rather more
difficult. .. In fact, we can actually prove that, in a certain sense,
there is no way to construct a join function with the type above using
only the operations of the two monads (see the appendix for an outline
of the proof). It follows that the only way that we might hope to form
a composition is if there are some additional constructions linking
the two component
And this composition is not even necessary commutative (swappable) as I demonstrated for Option and Future.
As an exercise, you can try to define FutureT's flatMap:
def flatMapF[B](f: A => F[Future[B]])(implicit F: Monad[F]): FutureT[F, B] =
FutureT(F.flatMap(value){ x: Future[A] =>
val r: Future[F[Future[B]] = x.map(f)
//you have to return F[Future[B]] here using only f and F.pure,
//where F can be List, Option whatever
})
basically the problem with such implementation is that you have to "extract" value from r which is impossible here, assuming you can't extract value from Future (there is no comonad defined on it) at least in a "non-blocking" context (like ScalaJs). This basically means that you can't "swap" Future and F, like Future[F[Future[B]] => F[Future[Future[B]. The latter is a natural transformation (morphism between functors), so that explains the first comment on this general answer:
you can compose monads if you can provide a natural transformation swap : N M a -> M N a
Applicatives however don't have such problems - you can easily compose them, but keep in mind that result of composition of two Applicatives may not be a monad (but will always be an applicative). Nested[Future, Option, T] is not a monad on T, regardless that both Option and Future are monads on T. Putting in simple words Nested as a class doesn't have flatMap.
It would be also helpful to read:
http://typelevel.org/cats/tut/applicative.html
http://typelevel.org/cats/tut/apply.html
http://typelevel.org/cats/tut/monad.html
http://typelevel.org/cats/tut/optiont.html
Putting it all together (F and G are monads)
F[G[T]] is a monad on G[T], but not on T
G_TRANSFORMER[F, T] required in order to get a monad on T from F[G[T]].
there is no MEGA_TRANSFORMER[G, F, T] as such transformer can't be build on top of monad - it requires additional operations defined on G (it seems like comonad on G should be enough)
every monad (including G and F) is applicative, but not every applicative is a monad
in theory F[G[T]] is an applicative over both G[T] and T. However scala requires to create NESTED[F, G, T] in order to get composed applicative on T (which is implemented in cats library).
NESTED[F, G, T] is applicative, but not a monad
That means you can compose Future x Option (aka Option[Future[T]]) to one single monad (coz OptionT exists), but you can't compose Option x Future (aka Future[Option[T]]) without knowing that Future is something else besides being a monad (even though they’re inherently applicative functors - applicative is not enough to neither build a monad nor monad transformer on it) . Basically:
OptionT can be seen as non-commutative binary operator defined as OptionT: Monad[Option] x Monad[F] -> OptionT[F, T]; for all Monad[F], T; for some F[T]. Or in general: Merge: Monad[G] x Monad[F] -> Monad[Merge]; for all T, Monad[F]; but only for **some of Monad[G]**, some F[T], G[T];
you can compose any two applicatives into one single applicative Nested: Applicative[F] x Applicative[G] -> Nested[F, G]; for all Applicative[F], Applicative[G], T; for some F[T], G[T],
but you can compose any two monads (inherently functors) only into one applicative (but not into monad).
Tony Morris gave a talk on monad transformers that explains this precise issue very well.
http://tonymorris.github.io/blog/posts/monad-transformers/
He uses haskell, but the examples are easily translatable to scala.