Is it possible to change monadic sequence? - scala

The problem: I have the following Future[Option[T]] monad and I would like to apply scalaz Monad Transformer OptionT to it. Cos I'm interested only in Optional result.
Question: Is it possible to produce Option[Future[T]] from Future[Option[T]] preserving the semantic?

Use .sequence:
scala> import scalaz._, Scalaz._, ...
scala> val a: Future[Option[Int]] = Future(None)
a: Future[Option[Int]] = Future(Success(None))
scala> val b = a.sequence
b: Option[Future[Int]] = None

Related

Summing a list of OptionT[Future, BigDecimal] in Scalaz

I have a list of type List[Result[BigDecimal]] that I want to sum.
type Result[A] = OptionT[Future, A]
The rule would be that if there is any Future(None) then we get the result Future(None).
I have the function [1]:
def sum[A: Monoid](as: List[A]): A = {
val M = implicitly[Monoid[A]]
as.foldLeft(M.zero)(M.append)
}
However, I am missing the Monoid instance for Result[BigDecimal]. How do I define it using Scalaz?
learning Scalaz - sum function
I'm not sure why Scalaz doesn't provide this instance—it does provide a Monoid[Future[A]] where A has a monoid instance, and where there's an implicit execution context in scope. You can easily make your own, though, either by defining an isomorphism between Result and Future[Option[?]] and then using IsomorphismMonoid, or [this wouldn't actually have the desired semantics] by just defining one directly:
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scalaz._, Scalaz._
type Result[A] = OptionT[Future, A]
implicit def resultMonoid[A: Monoid]: Monoid[Result[A]] = new Monoid[Result[A]] {
def zero: Result[A] = Monoid[A].zero.point[Result]
def append(f1: Result[A], f2: => Result[A]): Result[A] = (f1 |#| f2)(_ |+| _)
}
And then (using Scalaz's own suml, but your sum would work as well):
scala> List(OptionT(Future(1.some)), OptionT(Future(2.some))).suml
res1: scalaz.OptionT[scala.concurrent.Future,Int] = OptionT(List())
scala> scala.concurrent.Await.result(res1.run, scala.concurrent.duration.Duration.Inf)
res2: Option[Int] = Some(3)
For what it's worth, Cats provides this instance, but (like the Future[Option[?]] instance in Scalaz) it has None as identity.

Better Way to Handle Nested Monad?

Given a list of names:
scala> import scala.concurrent.Future
import scala.concurrent.Future
scala> import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.ExecutionContext.Implicits.global
scala> val names: Future[List[String]] =
Future.successful( List("Joe Foo", "Jane Bar") )
names: scala.concurrent.Future[List[String]] =
scala.concurrent.impl.Promise$KeptPromise#3dddbe65
And, a method that, for a given name, returns a Future[String] for that name's hobby:
scala> def getHobby(name: String): Future[String] = Future.successful( "poker" )
getHobby: (name: String)scala.concurrent.Future[String]
With names, i.e. Future[List[String]], I can get those names' hobby via:
scala> names.map(_.map(getHobby))
res3: scala.concurrent.Future[List[scala.concurrent.Future[String]]] =
scala.concurrent.impl.Promise$DefaultPromise#42c28305
But, then I have a somewhat hard-to-read, nested monad, Future[List[Future[String]].
I can clean it up:
scala> res3.map(Future.sequence(_))
res5: scala.concurrent.Future[scala.concurrent.Future[List[String]]] =
scala.concurrent.impl.Promise$DefaultPromise#4eaa375c
scala> res5.flatMap(identity)
res6: scala.concurrent.Future[List[String]] =
scala.concurrent.impl.Promise$DefaultPromise#101bdd1c
And then gets it value.
scala> res6.value
res7: Option[scala.util.Try[List[String]]] = Some(Success(List(poker, poker)))
But, is there a cleaner, more idiomatic way to perform the above work?
One approach is to flatten the data as it's retrieved.
scala> names.flatMap(x => Future.sequence(x.map(getHobby)))
res54: scala.concurrent.Future[List[String]] = scala.concurrent.impl.Promise$DefaultPromise#45cd45aa
Just for illustration (of nested monad), you also have "Scalaz Monad Transformers", described by Rama Nallamilli.
Take Future for example, all these cases below are monads nested within a monad.
Future[Option[T]]
Future[List[T]]
Future[scalaz.\/[A, B]]
In the case of a nested monad such as Future[List[Int]], Rama suggests:
When choosing which monad transformer to use, you always choose the inner most type, in this case List[Int] is our inner most type so we will use the (Scalaz) ListT monad transformer.
The ListT apply function is as follows:
def apply[A](a: M[List[A]]) = new ListT[M, A](a)
Therefore we can use this to convert our Future[List[Int]] to the ListT monad type which in this case will be a ListT[Future, Int].
We can now write our addition in terms of the new monad type which has abstracted the mapping of the Future:
# for {
i <- ListT(x)
j <- ListT(y)
} yield i + j
res20: ListT[Future, Int] = ListT(Success(List(5, 6, 7, 6, 7, 8, 7, 8, 9)))
In summary:
monad transformers give you a powerful abstraction to work on the underlying data of a monadic type when it itself is wrapped in a monad.
It reduces code complexity and enhances readability by abstracting the wiring of drilling down into the nested datatypes.
ScalaZ provides implementations of monad transformers for many types including EitherT, ListT, OptionT and ReaderT to name a few.

generic functions that operates on collections in scala

This seems like a simple question that I was sure have been asked before, but couldn't find what I was looking for.
How can one write a function that takes a collection as an argument (or anything that can be treated as a collection), perform some operations on it, and return a collection of the same type?
e.g:
scala> def foo[Repr <% Traversable[String]](repr: Repr) = repr.map(_.size)
foo: [Repr](repr: Repr)(implicit evidence$1: Repr => Traversable[String])Traversable[Int]
this works ok on some collections:
scala> foo(Vector("Hello","World"))
res0: Traversable[Int] = Vector(5, 5)
but surprising when I tried on other collections (e.g. Option):
scala> foo(Some("HelloWorld"))
res1: Traversable[Int] = List(10)
a small problem is the return type Traversable, which ideally would be the type of whatever was given to the method. the bigger problem is the actual implementation type: an Option became a List.
it gets even worse, when tried on classes (that behaves like collections) but have no implicit in scope for them. e.g: Try:
scala> import scala.util._
import scala.util._
scala> foo(Success("HelloWorld"))
<console>:12: error: No implicit view available from scala.util.Success[String] => Traversable[String].
foo(Success("HelloWorld"))
^
So, is there a way, to write a generic function, that when given a "collection like" argument, can operate on it's elements and return the correct type?
ideally, I would like to use it on anything (even Future, and Try) , but for my specific usage, I can do with just real collections & Option.
EDIT:
to illustrate a possible solution, (which forces me to copy&paste code, and so, is not what i'm looking for) is to simply write both functions without view bounds:
scala> :paste
// Entering paste mode (ctrl-D to finish)
def foo[Repr <: Traversable[String]](repr: Repr) = repr.map(_.size)
def foo(repr: Option[String]) = repr.map(_.size)
// Exiting paste mode, now interpreting.
foo: [Repr <: Traversable[String]](repr: Repr)Traversable[Int] <and> (repr: Option[String])Option[Int]
foo: [Repr <: Traversable[String]](repr: Repr)Traversable[Int] <and> (repr: Option[String])Option[Int]
scala> foo(Vector("bar"))
res2: Traversable[Int] = Vector(3)
scala> foo(Some("bar"))
res3: Option[Int] = Some(3)
The concept of mapping is represented by functors. One way to easily provide functor implementations for common classes is to use the scalaz library:
import scala.language.higherKinds
import scalaz.Functor
import scalaz.Scalaz._
def foo[El <: String, Coll[_]](repr: Coll[El])(implicit ev: Functor[Coll]) =
repr.map(_.size)
Now, this just works for List, Vector and Future:
scala> foo(Vector("Hello","World"))
res1: scala.collection.immutable.Vector[Int] = Vector(5, 5)
scala> foo(List("Hello","World"))
res2: List[Int] = List(5, 5)
scala> import scala.concurrent.Future
scala> import scala.concurrent.ExecutionContext.Implicits.global
scala> foo(Future("HelloWorld")) andThen PartialFunction(println(_))
Success(10)
Using it with Some is a bit of a problem, because only Option has a Functor implementation, not Some:
scala> foo(Some("HelloWorld"))
<console>:12: error: could not find implicit value for parameter ev: scalaz.Functor[Some]
foo(Some("HelloWorld"))
^
So you have to provide Option instead of Some to foo:
scala> foo(Some("HelloWorld"): Option[String])
res3: Option[Int] = Some(10)
scala> foo(Option("HelloWorld"))
res4: Option[Int] = Some(10)
scala> foo("HelloWorld".some) // This is from scalaz
res5: Option[Int] = Some(10)
And scalaz doesn't have any typeclass implementations for Try, so if you want to use Functor with Try, you'll have to provide the implementation yourself:
import scala.util.Try
import scalaz.Functor
implicit object TryIsFunctor extends Functor[Try] {
def map[A, B](fa: Try[A])(f: A => B): Try[B] = fa map f
}
Then foo will work with Try, but similar to Option, the argument should have the type Try, instead of Success or Failure:
scala> foo(Try("HelloWorld"))
res9: scala.util.Try[Int] = Success(10)
Also, I believe, there are no Functor implementations in scalaz for more general collection types, like Iterable or Seq.
Out of the common higher-order functions Functor only supports map. So to use flatMap and filter you have to provide different typeclasses instead of Functor. For example, scalaz.Monad supports map and flatMap, and scalaz.MonadPlus supports map, flatMap and filter.
And if you don't want to use scalaz, you'd probably have to make something very similar yourself with typeclasses, to get a good result type instead of Traversable. For example, using CanBuildFrom from the standard library.
I do think Kolmar is right about the general problem, but Scala does support duck-typing, so you can do this:
def foo[T[V]](duck: {def map[U](value: String=>U): T[_]}) ={
duck.map(_.size)
}
foo(Vector("bar")).toVector //> res0: Vector[_$2] = List(3)
foo(Some("bar")) //> res1: Option[_$2] = Some(3)
(toVector just to force the eval of the iterator that otherwise results)

Is there a way to flatten nested monads of different types?

I am not sure how to describe this problem, so I'll just show the type signatures.
I have an instance of the following:
val x:Future[F[Future[F[B]]]] = ???
And I want an instance of:
val y:Future[F[B]] = ???
F is a Monad, so I have the following methods:
def pure[A](a:A):F[A] = ???
def flatMap[A, B](fa:F[A], f:A => F[B]):F[B] = ???
def map[A, B](fa:F[A], f:A => B):F[B] = flatMap(fa, (a:A) => pure(f(a)))
I think the following should work, but it does not feel right:
x.flatMap { fWithFuture =>
val p = Promise[F[B]]
flatMap(fWithFuture, (futureF: Future[F[B]]) => {
p.completeWith(futureF)
pure(())
})
p.future
}
Is there a concept I'm missing?
A bit of background information. I am trying to define a function like this:
def flatMap[A, B](fa:Future[F[A]], f: A => Future[F[B]]):Future[F[B]] = ???
Maybe this is conceptually a weird thing. Any tips on useful abstractions are welcome.
As Rex Kerr notes above, you can often use a monad transformer to deal with a situation where you find yourself with alternating layers like this. For example, if F here is Option, you could use Scalaz 7.1's OptionT monad transformer to write your flatMap:
import scalaz._, Scalaz._
type F[A] = Option[A]
def flatMap[A, B](fa: Future[F[A]], f: A => Future[F[B]]): Future[F[B]] =
OptionT(fa).flatMap(f andThen OptionT.apply).run
OptionT[Future, A] here is a kind of wrapper for Future[Option[A]]. If your F is List, just replace OptionT with ListT and run with underlying (and so on).
The nice thing is that when you're working with OptionT[Future, A], for example, you can generally avoid ending up with Future[Option[Future[Option[A]]]] in the first place—see my answer here for some more detailed discussion.
One drawback is that not all monads have transformers. For example, you can put Future at the bottom of the stack (as I've done above), but there's not really a useful way to define FutureT.
This may answer the "And I want an instance of:" part.
$ scala
Welcome to Scala version 2.10.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_05).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import scala.concurrent.Future
import scala.concurrent.Future
scala> import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.ExecutionContext.Implicits.global
scala> Future(List(Future(1),Future(2),Future(3))) // Future[F[Future[B]]]
res0: scala.concurrent.Future[List[scala.concurrent.Future[Int]]] = scala.concurrent.impl.Promise$DefaultPromise#41ab013
scala> res0.map(Future.sequence(_)) // transformed to Future[Future[F[B]]
res1: scala.concurrent.Future[scala.concurrent.Future[List[Int]]] = scala.concurrent.impl.Promise$DefaultPromise#26a4842b
scala> res1.flatMap(identity) // reduced to Future[F[B]]
res2: scala.concurrent.Future[List[Int]] = scala.concurrent.impl.Promise$DefaultPromise#4152d38d
Hopefully the below flatMap definition should give an idea of transforming the types :)
I replaced F with a List type for ease of understanding.
scala> def flatMap[A, B](fa:Future[List[A]], f: A => Future[List[B]]):Future[List[B]] = {
| val x: Future[List[Future[List[B]]]] = fa.map(_.map(f))
| val y: Future[Future[List[List[B]]]] = x.map(Future.sequence(_))
| val z: Future[Future[List[B]]] = y.map(_.map(_.flatten))
| z.flatMap(identity)
| }
flatMap: [A, B](fa: scala.concurrent.Future[List[A]], f: A => scala.concurrent.Future[List[B]])scala.concurrent.Future[List[B]]

Ordering and Ordered and comparing Options

Given:
case class Person(name: String)
and trying to do:
scala> List(Person("Tom"), Person("Bob")).sorted
results in a complaint about missing Ordering.
<console>:8: error: could not find implicit value for parameter ord: Ordering[Person]
List(Person("Tom"), Person("Bob")).sorted
However this:
case class Person(name: String) extends Ordered[Person] {
def compare(that: Person) = this.name compare that.name }
works fine as expected:
scala> List(Person("Tom"), Person("Bob")).sorted
res12: List[Person] = List(Person(Bob), Person(Tom))
although there's no Ordering or implicits involved.
Question #1: what's going on here? (My money is on something implicit...)
However, given the above and the fact that this:
scala> Person("Tom") > Person("Bob")
res15: Boolean = true
works, and that also this:
scala> List(Some(2), None, Some(1)).sorted
works out of the box:
res13: List[Option[Int]] = List(None, Some(1), Some(2))
I would expect that this:
scala> Some(2) > Some(1)
would also work, however it does not:
<console>:6: error: value > is not a member of Some[Int]
Some(2) > Some(1)
Question #2: why not, and how can I get it to work?
If you install the slightly-too-magical-for-default-scope bonus implicits, you can compare options like so:
scala> import scala.math.Ordering.Implicits._
import scala.math.Ordering.Implicits._
scala> def cmpSome[T: Ordering](x: Option[T], y: Option[T]) = x < y
cmpSome: [T](x: Option[T], y: Option[T])(implicit evidence$1: Ordering[T])Boolean
The import gives you an implicit from an Ordering to the class with the infix operations, so that it's enough to have the Ordering without another import.
Concerning your first question: Ordered[T] extends Comparable[T]. The Ordering companion object provides an implicit Ordering[T] for any value that can be converted into a Comparable[T]:
implicit def ordered[A <% Comparable[A]]: Ordering[A]
There is no implicit conversion A : Ordering => Ordered[A] - that's why Some(1) > Some(2) will not work.
It is questionable if it is a good idea to define such a conversion as you may end up wrapping your objects into Ordered instances and then create an Ordering of that again (and so on...). Even worse: you could create two Ordered instances with different Ordering instances in scope which is of course not what you want.
The definition of List's sorted method is:
def sorted [B >: A] (implicit ord: Ordering[B]): List[A]
So yes, implicit things are happening, but many classes in the standard library have implicit objects associated with them without you having to import them first.
The Ordering companion object defines a bunch of implicit orderings. Among these is an OptionOrdering and IntOrdering, which helps explain the ability of a list to call sorted.
To gain the ability to use operators when there is an implicit conversion available, you need to import that object, for example:
def cmpSome(l:Option[Int], r:Option[Int])(implicit ord:Ordering[Option[Int]]) = {
import ord._
l < r
}
scala> cmpSome(Some(0), Some(1))
res2: Boolean = true
To answer your second question, why can't you do this: Some(2) > Some(1)
You can, with an import and working with Option[Int] rather than Some[Int].
# import scala.math.Ordering.Implicits._
import scala.math.Ordering.Implicits._
# Some(2) > Some(1) // doesn't work
cmd11.sc:1: value > is not a member of Some[Int]
val res11 = Some(2) > Some(1)
^
Compilation Failed
# (Some(2): Option[Int]) > (Some(1): Option[Int]) // Option[Int] works fine
res11: Boolean = true
# Option(2) > Option(1)
res12: Boolean = true
# (None: Option[Int]) > (Some(1): Option[Int])
res13: Boolean = false
In practise your types will probably be of Option[Int] rather than Some[Int] so it won't be so ugly and you won't need the explicit upcasting.
I assume you understand why sorted does not work when you do not pass in an Ordering and none is available in scope.
As to why the sorted function works when you extend your class from Ordered trait. The answer is that when you extend from Ordered trait, the code type checks as the trait contains function like <,> etc. So there is no need to do implicit conversion and hence no complains about the missing implicit Ordering.
As for your second question, Some(2) > Some(1) will not work because Some does not extend the trait Ordered, neither does there seem to be any implicit function in scope that implicitly converts a Some to something that has the function >
Thanks for a detailed question with examples.
My answer is based what I learnt from a great article here: http://like-a-boss.net/2012/07/30/ordering-and-ordered-in-scala.html
All credit to the author here.
Quoting the article:
Coming back to our Box example - the scala library defines an implicit conversion between Ordered[T] and Ordering[T] and vice-versa.
The companion object of Ordered in https://github.com/scala/scala/blob/2.12.x/src/library/scala/math/Ordered.scala provides the required conversion here:
/** Lens from `Ordering[T]` to `Ordered[T]` */
implicit def orderingToOrdered[T](x: T)(implicit ord: Ordering[T]): Ordered[T] =
new Ordered[T] { def compare(that: T): Int = ord.compare(x, that) }
However the reverse conversion isn't defined and I am not sure why?