Handling Option[A] in a function - scala

I need a function which does something like the code below
def function[A,B](a: Option[A], f: Function[A,B]) = {
a match {
case None => None
case Some(v) => Some(f(v))
}
}
Is there any scala built-in function which does the same?

def function[A,B](a: Option[A], f: Function[A,B]) = {
a.map(f(_))
}
Option can be treated as a Monad so many operations such as map, flatMap, and filter are available on it.
http://www.scala-lang.org/api/current/index.html#scala.Option

Related

scala syntax explanation involving higher order functions, type parameter and return type

I am having problems understanding the Scala syntax, please advice. I have two snippets of code.
abstract class Try[T] {
def flatMap[U](f: T => Try[U]): Try[U] = this match {
case Success(x) => try f(x) catch { case NonFatal(ex) => Failure(ex) }
case fail: Failure => fail
}
}
My understanding:
flatMap received as parameter a function f. In turn this function f
receives type parameter T and returns Try of type parameter U.
flatMap ultimately return Try of type parameter U.
Q1 - Is my understanding correct?
Q2 - what is the relation between the return type from f (namely Try[U]) and the return type of flat map Try[U]? Does it have to be the same?
def flatMap[U](f: T => Try[U]): Try[U]
Or can I somehow have something like
def flatMap[U](f: T => Option[U]): Try[U]
In the last snippet of code, I guess that, after I use the function f inside my flatMap, I would need to make the connection between the output of f (namely Option[U]) and the final output demanded by flatMap (I mean Try[U])
EDIT
This code is taken from a scala course. here is the full code (some people asked about it). I just want to understand the syntax.
abstract class Try[T] {
def flatMap[U](f: T => Try[U]): Try[U] = this match {
case Success(x) => try f(x) catch { case NonFatal(ex) => Failure(ex) }
case fail: Failure => fail
}
def map[U](f: T => U): Try[U] = this match {
case Success(x) => Try(f(x))
case fail: Failure => fail
}
}
Q1 - Is my understanding correct?
It's hard to comment based on your sample code which has method implementation in an abstract class while no concrete classes are defined. Lets consider the following toy version of Try extracted from the Scala API with the flatMap implementation in its concrete classes:
import scala.util.control.NonFatal
sealed abstract class MyTry[+T] {
def flatMap[U](f: T => MyTry[U]): MyTry[U]
}
object MyTry {
def apply[T](r: => T): MyTry[T] =
try MySuccess(r) catch { case NonFatal(e) => MyFailure(e) }
}
final case class MyFailure[+T](exception: Throwable) extends MyTry[T] {
override def flatMap[U](f: T => MyTry[U]): MyTry[U] =
this.asInstanceOf[MyTry[U]]
}
final case class MySuccess[+T](value: T) extends MyTry[T] {
override def flatMap[U](f: T => MyTry[U]): MyTry[U] =
try f(value) catch { case NonFatal(e) => MyFailure(e) }
}
Testing it out with the following function f: T => MyTry[U] where T = String and U = Int, I hope it helps answer your question:
val f: String => MyTry[Int] = s => s match {
case "bad" => MyFailure(new Exception("oops"))
case s => MySuccess(s.length)
}
MyTry("abcde").flatMap(f)
// res1: MyTry[Int] = MySuccess(5)
MyTry("bad").flatMap(f)
// res2: MyTry[Int] = MyFailure(java.lang.Exception: oops)
Q2 - what is the relation between the return type from f (namely Try[U])
and the return type of flat map Try[U]? Does it have to be the same?
In Scala, flatMap is a common method defined in many of Scala containers/collections such as Option[T], List[T], Try[T], Future[T], with a standard signature:
class Container[T] {
def flatMap[U](f: T => Container[U]): Container[U]
}
If you want to have a special map that takes a T => Container1[U] function and returns a Container2[U], it'd probably best not to name it flatMap.
Q1 Largely correct, but just to clarify, all of this happens at compile time - T is not known at runtime (see here)
Q2 Of course you can create a method with signature
...[U](f: T => Option[U]): Try[U]
and you're free to call that method flatMap, but it won't be a standard flatMap:
trait T[A] {
flatMap[B](f: A => T[B]): T[B]
}
There are mathematical reasons for the form of flatMap (which also have implications in Scala's implementation of for expressions). To avoid confusion ...
Rather than altering flatMap's signature, wrap your T => Option[U] with an Option[U] => Try[U] to create a T => Try[U] before passing it to flatMap.

Monad transformer flatMap working

I´ve been playing monad transformer, and I just create one Future[Option]. But after read some blogs there´s something that is not explained and I don't understand.
Here in the implementation of my map and flatMap, in the flatMap once that I get the value of my option, and I apply the function over the value, I have to invoke over the function f(a) the .Value_passed_in_the_case_class(in this case future)
case class FutOpt[A](future: Future[Option[A]]) {
def map[B](f: A => B): FutOpt[B] = {
FutOpt(future.map(option => option.map(value => f(value)))
.recoverWith {
case e: Exception =>
Future.successful(Option.empty)
})
}
def flatMap[B](f: A => FutOpt[B]): FutOpt[B] =
FutOpt(future.flatMap(option => option match {
case Some(a) => f(a).future --> WHAT THIS .future IS DOING?
case None => Future.successful(None)
}))
}
What is happening there?, and how works?.
Regards.
What is happening there?
flatMap expects you to return it a FutOpt[B]:
def flatMap[B](f: A => FutOpt[B]): FutOpt[B]
The signature of your case class requires you to pass in a Future[Option[A]]:
case class FutOpt[A](future: Future[Option[A]])
This line of code:
FutOpt(future.flatMap(option => option match {
case Some(a) => f(a).future
Is constructing a new instance of FutOpt[B], and it needs a value of type Future[Option[B]] in order to be able to construct itself properly. f(a) returns a FutOpt[B], not a Future[Option[B]], and that is why it needs to access .future, which is of type Future[Option[B]].

scala lifting function having with a collection as argument

I have a class which accepts a function f: Option[Seq[Option[A]]] => Option[A]]
case class Function[A](operator: Option[Seq[Option[A]]] => Option[A], name: String, arity: Int)
What i would like is for the user of this class to be able to not have to worry about the Option framework. So the user would pass a function g: Seq[A] => A and under the hood i would lift that function. The lifting part is what i'm not being able to do.
This is what i have (using optionInstance.lift of scalaz) :
object Function {
def apply[A](operator: Seq[A] => A) = new Function(optionInstance.lift(operator),"a", 1)
}
However this does not compile since the lift operator is returning Option[Seq[A]] instead of Option[Seq[Option[A]]]. How can this be done?
Here's an example of how to convert between your two prototypes :
def f[A]: Seq[A] => A = ???
def g[A]: Option[Seq[Option[A]]] => Option[A] = {
{
case None => None
case Some(seq) if seq.exists(_.isEmpty) => None
case Some(seq) => Some(f(seq.flatten))
}
}
You can use this to transform your operator
If you would like to return Option[Seq[Option[A]]] you have to first transform your Seq[A] into a Seq[Option[A]] before doing the lift

Scala: How do I write the type of the function that sortBy takes?

I want to pass the parameter that List.sortBy takes through to another function. My code looks something like this:
//Scala
def sortAndMore(list: List[(String, _)], sortFn: Option[???] = None) = {
val maybeSortedList = sortFn match {
case None => list
case Some(fn) => list.sortBy(fn)
}
// do some more stuff with this list
}
val myList = ("one", 1)::("three", 3)::("two", 2)::Nil
sortAndMore(myList, Some(_._1 /*???*/))
So in the end I want to have the same result as this gives:
myList.sortBy(_._1)
What is the type of Option in the sortAndMore function?
The Scala API for scala.collection.immutable.List says this:
def sortBy [B] (f: (A) ⇒ B)(implicit ord: Ordering[B]): List[A]
I tried several things, but I just don't know the correct syntax, and wasn't lucky guessing it. Any hints are very much appreciated, especially with a pointer to why the syntax has to be that way.
Here is my solution (compiles on my terminal)
def sortAndMore(list: List[(String,_)], sortFn: Option[((String,_))=>String] = None) = {
val maybeSortedList = sortFn match {
case Some(fn) => list.sortBy(fn)
case None => list
}
}
sortAndMore(myList, Some(_._1))

Is there a built-in more elegant way of filtering-and-mapping a collection by element type?

If I want to narrow, say, an Iterable[A] for all elements of a particular type (e.g. String) I can do:
as filter { _.isInstanceOf[String] }
However, it's obviously desirable to use this as an Iterable[String] which can be done via a map:
as filter { _.isInstanceOf[String] } map { _.asInstanceOf[String] }
Which is pretty ugly. Of course I could use flatMap instead:
as flatMap[String] { a =>
if (a.isInstanceOf[String])
Some(a.asInstanceOf[String])
else
None
}
But I'm not sure that this is any more readable! I have written a function, narrow, which can be used via implicit conversions:
as.narrow(classOf[String])
But I was wondering if there was a better built-in mechanism which I have overlooked. Particularly as it would be nice to be able to narrow a List[A] to a List[String], rather than to an Iterable[String] as it will be with my function.
The Scala syntax sugar for isInstanceOf / asInstanceOf is pattern matching:
as flatMap { case x: String => Some(x); case _ => None }
Because that uses flatMap, it should usually return the same collection you had to begin with.
On Scala 2.8, there's an experimental function that does that kind of pattern, defined inside the object PartialFunction. So, on Scala 2.8 you can do:
as flatMap (PartialFunction.condOpt(_ : Any) { case x: String => x })
Which looks bigger mostly because I did not import that function first. But, then again, on Scala 2.8 there's a more direct way to do it:
as collect { case x: String => x }
For the record, here's a full implementation of narrow. Unlike the signature given in the question, it uses an implicit Manifest to avoid some characters:
implicit def itrToNarrowSyntax[A](itr: Iterable[A]) = new {
def narrow[B](implicit m: Manifest[B]) = {
itr flatMap { x =>
if (Manifest.singleType(x) <:< m)
Some(x)
else
None
}
}
}
val res = List("daniel", true, 42, "spiewak").narrow[String]
res == Iterable("daniel", "spiewak")
Unfortunately, narrowing to a specific type (e.g. List[String]) rather than Iterable[String] is a bit harder. It can be done with the new collections API in Scala 2.8.0 by exploiting higher-kinds, but not in the current framework.
You may use in future:
for(a :Type <- itr) yield a
But it doesn't work now.
For more information, go to the following links:
http://lampsvn.epfl.ch/trac/scala/ticket/1089
http://lampsvn.epfl.ch/trac/scala/ticket/900
Shape preserving: I'm a bit rushed right now so I'm leaving the cast in there, but I'm pretty sure it can be eliminated. This works in trunk:
import reflect.Manifest
import collection.Traversable
import collection.generic.CanBuildFrom
import collection.mutable.ListBuffer
object narrow {
class Narrower[T, CC[X] <: Traversable[X]](coll: CC[T])(implicit m1: Manifest[CC[T]], bf: CanBuildFrom[CC[T], T, CC[T]]) {
def narrow[B: Manifest]: CC[B] = {
val builder = bf(coll)
def isB(x: T): Option[T] = if (Manifest.singleType(x) <:< manifest[B]) Some(x) else None
coll flatMap isB foreach (builder += _)
builder mapResult (_.asInstanceOf[CC[B]]) result
}
}
implicit def toNarrow[T, CC[X] <: Traversable[X]](coll: CC[T])(implicit m1: Manifest[CC[T]], bf: CanBuildFrom[CC[T], T, CC[T]]) =
new Narrower[T,CC](coll)
def main(args: Array[String]): Unit = {
println(Set("abc", 5, 5.5f, "def").narrow[String])
println(List("abc", 5, 5.5f, "def").narrow[String])
}
}
Running it:
Set(abc, def)
List(abc, def)