With Scalaz, a function can be mapped over another function. When would I want to use map over andThen? Is there a clear advantage using map? Thanks
For example,
val f: Int => Int = (a) => a + 10
val g: Int => Int = (a) => a * 100
(f map g map {_*3})(10) == (f andThen g andThen {_*3})(10) // true
Setting aside implementation details for a moment, map is andThen for functions (under the functor instance for A => ?), and it doesn't really make a lot of sense to talk about preferring one over the other if we're talking about functions specifically and not some higher level of abstraction.
What methods like map (and type classes like Functor more generally) allow us to do is abstract over specific types or type constructors. Suppose we want to write a incrementResult method that works on both A => Int or Kleisli[Option, A, Int], for example. These types don't have anything in common in terms of inheritance (short of AnyRef, which is useless), but A => ? and Kleisli[Option, A, ?] are both functors, so we could write this:
import scalaz._, Scalaz._
def incrementResult[F[_]: Functor](f: F[Int]): F[Int] = f.map(_ + 1)
And then use it like this (note that I'm using kind-projector to simplify the type syntax a bit):
scala> val plainOldFuncTriple: Int => Int = _ * 3
plainOldFuncTriple: Int => Int = <function1>
scala> val optionKleisliTriple: Kleisli[Option, Int, Int] = Kleisli(i => Some(i * 3))
optionKleisliTriple: scalaz.Kleisli[Option,Int,Int] = Kleisli(<function1>)
scala> val f = incrementResult[Int => ?](plainOldFuncTriple)
f: Int => Int = <function1>
scala> val k = incrementResult[Kleisli[Option, Int, ?]](optionKleisliTriple)
k: scalaz.Kleisli[Option,Int,Int] = Kleisli(<function1>)
scala> f(10)
res0: Int = 31
scala> k(10)
res1: Option[Int] = Some(31)
In this case specifically there are better ways to implement this operation, but it shows the general idea—we couldn't write a single method that works for both ordinary functions and Kleisli arrows using andThen, but we can with the extra level of abstraction that map gives us.
So to answer your question—you'd use map if you want to abstract over all type constructors that have a functor instance, but if you're working specifically with functions, map is andThen, and—as long as we're still setting aside implementation details—it doesn't matter which you choose.
Footnote: the map that Scalaz's syntax package gives you for values of types that have functor instances is implemented as an extension method, so there's a tiny bit of overhead (both at compile time and runtime) involved in using map instead of andThen on a function. If you're only working with functions and don't need the extra abstraction, then, you might as well go with andThen.
Related
For the record I find it very annoying that functions are not automatically curried in Scala. I'm trying to write a factory that takes in any function and returns a curried version:
def curry(fn:(_ => _)) = (fn _).curried
Basically what I have defined here is a function curry that takes as an argument a function fn that is of type _ => _ and returns a curried version of function fn. Obviously this didnt work because Java.
This was the error I got:
error: _ must follow method; cannot follow fn.type
def curry(fn:(_ => _)) = (fn _).curried
Can any gurus out there help me figure out why this doesnt work? I don't mean to sound snarky, I am used to functional languages treating all types as functions. Please help this Scala newbie.
(I tagged this question with haskell because I'm trying to get Scala functions to behave like Haskell functions :'(
UPDATE
Just to clarify, I need a curryN function, so a function that curries any other function regardless of its arity.
Side note, some people have pointed out that increasing the number of fn's arguments would solve the problem. Nope:
def curry2(fn:((_, _) => _)) = (fn _).curried
error: _ must follow method; cannot follow fn.type
def curry2(fn:((_, _) => _)) = (fn _).curried
Scala doesn't allow you to abstract over the arity of a function. Thus, you need to use a typeclass-style approach (which allows you to abstract over just about anything, after you do all the manual work for it).
So, in particular, you do something like
sealed trait FunctionCurrier[Unc, Cur] { def apply(fn: Unc): Cur }
final class Function2Currier[A, B, Z]
extends FunctionCurrier[(A, B) => Z, A => B => Z] {
def apply(fn: (A, B) => Z): (A => B => Z) = fn.curried
}
// Repeat for Function3 through Function21
implicit def makeCurrierForFunction2[A, B, Z]: Function2Currier[A, B, Z] =
new Function2Currier[A, B, Z]
// Again, repeat for Function3 through Function21
def curryAll[Unc, Cur](fn: Unc)(implicit cf: FunctionCurrier[Unc, Cur]): Cur =
cf(fn)
Now you can use it like so:
scala> def foo(a: Int, b: String) = a < b.length
foo: (a: Int, b: String)Boolean
scala> curryAll(foo _)
res0: Int => (String => Boolean) = <function1>
There is probably already something like this in Shapeless, but in this case you can roll your own, albeit with some tedium (and/or a code generator).
(Note: if you want to "curry" A => Z, you can write a Function1Currier that just returns the function untouched.)
This can be done using the curried method of functions. You need to access the function itself as a partially applied function and get its curried form, like so:
def fn(i: Int, j: Int) = i + j
val fnCurryable = (fn _).curried
val fnCurried = fnCurryable(1)
println(fnCurried(2))
//prints 3
The same second line would work to curry any function with 2-22 arguments due to scala's powerful type inference. Also, remember that you can declare your functions to be curryable in their declaration. This would do the same as above:
def fnCurryable(i: Int)(j: Int) = i + j
The use of multiple argument lists means this function is called as fnCurryable(1)(2) and can NEVER be called as fnCurryable(1, 2). This conversion is basically what .curried does.
This is based on the function traits described on:
http://www.scala-lang.org/api/2.11.8/index.html#scala.package
def toCurry[A](f: (A, A) => A): A => A => A = x => f(x, _)
val addTwoNum = (x: Int, y: Int) => x + y
val curriedAddTwoNum = toCurry(addTwoNum)
val part1Curry = curriedAddTwoNum(5)
println(part1Curry(2))
For additional arity, you would simply need to add additional params to the above function definition.
Otherwise, you may want to do something like Can you curry a function with varargs in scala?
I have a function in a context, (in a Maybe / Option) and I want to pass it a value and get back the return value, directly out of the context.
Let's take an example in Scala :
scala> Some((x:Int) => x * x)
res0: Some[Int => Int] = Some(<function1>)
Of course, I can do
res0.map(_(5))
to execute the function, but the result is wrapped in the context.
Ok, I could do :
res0.map(_(5)).getOrElse(...)
but I'm copy/pasting this everywhere in my code (I have a lot of functions wrapped in Option, or worst, in Either...).
I need a better form, something like :
res0.applyOrElse(5, ...)
Does this concept of 'applying a function in a concept to a value and immediatly returning the result out of the context' exists in FP with a specific name (I'm lost in all those Functor, Monad and Applicatives...) ?
You can use andThen to move the default from the place where you call the function to the place where you define it:
val foo: String => Option[Int] = s => Some(s.size)
val bar: String => Int = foo.andThen(_.getOrElse(100))
This only works for Function1, but if you want a more generic version, Scalaz provides functor instances for FunctionN:
import scalaz._, Scalaz._
val foo: (String, Int) => Option[Int] = (s, i) => Some(s.size + i)
val bar: (String, Int) => Int = foo.map(_.getOrElse(100))
This also works for Function1—just replace andThen above with map.
More generally, as I mention above, this looks a little like unliftId on Kleisli, which takes a wrapped function A => F[B] and collapses the F using a comonad instance for F. If you wanted something that worked generically for Option, Either[E, ?], etc., you could write something similar that would take a Optional instance for F and a default value.
You could write something like applyOrElse using Option.fold.
fold[B](ifEmpty: ⇒ B)(f: (A) ⇒ B): B
val squared = Some((x:Int) => x * x)
squared.fold {
// or else = ifEmpty
math.pow(5, 2).toInt
}{
// execute function
_(5)
}
Using Travis Browns recent answer on another question, I was able to puzzle together the following applyOrElse function. It depends on Shapeless and you need to pass the arguments as an HList so it might not be exactly what you want.
def applyOrElse[F, I <: HList, O](
optionFun: Option[F],
input: I,
orElse: => O
)(implicit
ftp: FnToProduct.Aux[F, I => O]
): O = optionFun.fold(orElse)(f => ftp(f)(input))
Which can be used as :
val squared = Some((x:Int) => x * x)
applyOrElse(squared, 2 :: HNil, 10)
// res0: Int = 4
applyOrElse(None, 2 :: HNil, 10)
// res1: Int = 10
val concat = Some((a: String, b: String) => s"$a $b")
applyOrElse(concat, "hello" :: "world" :: HNil, "not" + "executed")
// res2: String = hello world
The getOrElse is most logical way to do it. In regards to copy/pasting it all over the place - you might not be dividing your logic up on the best way. Generally, you want to defer resolving your Options (or Futures/etc) in your code until the point you need to have it unwrapped. In this case, it seems more sensible that your function takes in an an Int and returns an Int, and you map your option where you need the result of that function.
I have a mapper function defined as such:
def foo(x:Int) = if (x>2) x*2
the type signature of this method being Int => AnyVal. Now if I map this function over a list of integers:
scala> List(-1,3,-4,0,5).map(foo)
res0: List[AnyVal] = List((), 6, (), (), 10)
I need a way of filtering out the Units from the Ints like so:
scala> res0.filter(_.isInstanceOf[Int]).map(_.asInstanceOf[Int])
res1: List[Int] = List(6, 10)
Everything seems concisely expressed until I have to do the filter-map on res0 to extract the values I care about. I could use matchers or an if-else in foo to always ensure I return an Int but I'd still need to filter the unwanted values resulting from the map operation.
Can any of the well-seasoned Scala developers reading this provide some additional insight into what's good or bad about this approach especially as my collection grows large (e.g. maybe this collection is a distributed Spark RDD)? Are there more idiomatic ways of doing this functionally?
In this case I suggest you to use collect with PartialFunction, if you need to drop all ints that are smaller than 2
val foo: PartialFunction[Int, Int] = {
case x if x > 2 => x*2
}
println(List(-1,3,-4,0,5).collect(foo))
Your original foo has type Int => AnyVal, because scalac transforms it in something like
def foo(x: Int) = if (x > 2) x*2 else () // () === Unit
and common super type for Int and Unit is AnyVal
I am experimenting with scalaz. I tried writing code in applicative code. I wrote code like this:
val max: Option[Int] = (a |#| b) { math.max(_, _) }
I didn't like this code very much. I would like to code which is closer to Haskell style, something like this:
val max: Option[Int] = { math.max(_, _) } <$> a <*> b
Is this possible. And why scalaz didn't implement it this way?
Scala's type inference, is much more limited than in Haskell (identifier overloading, which comes with the JVM being one of the reasons). Inferences flows from left to right, and the type of the arguments of a function may be deduced from previous context (if at the place of the definition, a function with arg type A is expected), but not from how they are used in the definition. Scalaz syntax makes the arguments types available. Reversing it would most of the time force you to write the function arguments types, e.g.
{math.max(_: Int, _: Int) } <$> a <*> b
You can translate the Haskell version directly into Scala, if you're willing to be a little more verbose:
import scalaz._, Scalaz._
val a = Option(1)
val b = Option(2)
val f: Int => Int => Int = x => math.max(x, _)
val c = b <*> (a map f)
Or, as a one-liner:
val c = 2.some <*> 1.some.map(x => math.max(x, _: Int))
Or:
val c = 2.some <*> (1.some map (math.max _).curried)
The order is reversed because these are method calls instead of infix operators, but it's essentially the same thing as max <$> a <*> b: we map the function over the first item, and then apply the result to the second.
What I'm looking for is this function:
def maybe[A, B](a: Option[A])(f: A => B)(g: () => B): B = a match
{
case Some(x) => f(x)
case None => g()
}
It's in the Haskell prelude so I'm thinking it might be in the Scala standard library somewhere and I've just missed it. I hate having to recode it in projects so I'm wondering if anyone knows where it is, or if it's definitively not there. Or is there a better method for getting this functionality?
Other answers have given the map + getOrElse composition. Just for the record, you can "add" a maybe function to Option in the following way:
implicit def optionWithMaybe[A](opt: Option[A]) = new {
def maybe[B](f: A=>B)(g: =>B) = opt map f getOrElse g
}
It's worth noting that the syntax of higher-order functions in Scala is usually nicer when the function parameter comes last. Thus, a better way to organize maybe would be as follows:
def maybe[B](g: =>B)(f: A=>B) = opt map f getOrElse g
This could be used as follows:
val opt: Option[String] = ...
opt.maybe("") { _.toUpperCase }
You could do
val opt:Option[A] = // ...
val result:B = opt.map(f).getOrElse(g());
getOrElse takes a by-name parameter, so g will only be evaluated if opt is None.
The method would be called fold if it were to adhere to convention (see Either.fold which is the catamorphism for Either).
You can use scalaz, and then you have an implicit conversion to OptionW which has fold, or you can use Scala 2.10.0-M3 and use the builtin Option.fold
scala> Some(1).fold(5)(_ * 2)
res5: Int = 2
scala> (None: Option[Int]).fold(5)(_ * 2)
res7: Int = 5
Note that the scalaz fold signature is fold[X](some: A => X, none: => X), while the builtin seems to be fold[X](none: => X)(some: A => X).
I don't think there is. The best I could come up with is to chain Option's "map" and "getOrElse" together:
scala> var a: Option[String] = Some("hello")
a: Option[String] = Some(hello)
scala> a.map(_.toUpperCase).getOrElse("empty")
res19: java.lang.String = HELLO
scala> a = None
a: Option[String] = None
scala> a.map(_.toUpperCase).getOrElse("empty")
res21: java.lang.String = empty
I don't think there is. However, I'd write it to take g by name:
def maybe[A, B](a: Option[A])(f: A => B)(g: => B): B = a.map(f).getOrElse(g)
This is more Scala- and Haskell-like and a bit nicer to use.
I'd use Option.fold for this:
opt.fold(g)(f)
Note that g is by-name, just like getOrElse. Also note the inversion of the cases.