I've got a class with a collections of Foos we'll call Bar. Foo has a number of number-returning methods that we want to aggregate at the Bar level, like so:
def attribute1(inputs: Map[Int, Double]) =
foos.foldLeft(0d)((sum, foo) => sum + foo.attribute1(inputs(foo.id)))
To aggregate these various attributes, I can have n functions of the form
def attributeN(inputs: Map[Int, Double]) =
foos.foldLeft(0d)((sum, foo) => sum + foo.attributeN(inputs(foo.id)))
However, that's ugly - I hate the fact that the iteration and summation are repeated. I want to abstract that, so I can do something like:
def attribute1(inputs: Map[Int, Double]) = aggregate(Foo.attribute1, inputs)
private def aggregate(f: Double => Double) = foos.foldLeft(0d)((sum, foo) => sum + foo.f(inputs(foo.id)
Of course, that does not work as one cannot reference Foo.attribute1 as a function - . is not a function instance.
I've basically stumbled through various solution, but every one results in code for each aggregation method at least as verbose or complex as what we have with no helper, and I'm left with the duplication of the iteration.
I may be just hoping for too much here, but I am virtually certain there is an elegant way to do this is Scala that is escaping me. So, any of the Scala gurus here who answers - thanks in advance!
I'm not sure I get what you're trying to do, but in scala a number-returning method like this:
def attribute1 = 5
IS a function. Well, sort of... It can be seen as a function with type () => Int (takes no argument, returns an Integer). You just need to use the omnipresent _ to tell scala to turn attribute1 into a function.
See if this helps as a starting point:
scala> class Foo {
| def attribute1=5
| def attribute2=2
| }
defined class Foo
scala> val foo=new Foo
foo: Foo = Foo#4cbba0bd
// test takes a function of type () => Int and just applies it (note
// the f() followed by () in the right-hand side to say we want to apply f
scala> def test(f: () => Int) = f()
test: (f: () => Int)Int
// the _ after foo.attribute1 tells scala that we want to use
// res2.attribute as a function, not take its value
scala> test(foo.attribute1 _)
res0: Int = 5
So basically what you're asking for is a way to address a specific method on multiple instances, right? If so, it's easily solvable:
trait Foo {
def id : Int
def attribute1( x : Double ) : Double
}
def aggregate( f : (Foo, Double) => Double, inputs : Map[Int, Double] ) =
foos.foldLeft(0d)( (sum, foo) => sum + f(foo, inputs(foo.id)) )
def aggregateAttribute1(inputs: Map[Int, Double]) =
aggregate(_.attribute1(_), inputs)
The key to this solution is _.attribute1(_) which is a sugarred way of writing
(foo, input) => foo.attribute1(input)
Building on #Nikita's answer, if you want to remove a bit more redundancy from your boring methods, you can curry the aggregate method:
def aggregate(f: (Foo, Double) => Double)(inputs: Map[Int, Double]): Double =
foos.foldLeft(0d)((sum, foo) => sum + f(foo, inputs(foo.id)))
def aggregateAttribute1: Map[Int, Double] => Double =
aggregate(_.attribute1(_))
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?
According to ScalaByExample:
A curried function definition def f (args1) ... (argsn) = E where n >
1 expands to
def f (args1) ... (argsn−1) = { def g (argsn) = E ; g }
Or, shorter, using an anonymous function:
def f (args1) ... (argsn−1) = ( argsn ) => E
Uncurried version:
def f(x: Int): Int => Int = {
y: Int => x * y
} //> f: (x: Int)Int => Int
def f1 = f(10) //> f1: => Int => Int
f1(5)
Curried version:
def g(x: Int)(y: Int) = {
x * y
} //> g: (x: Int)(y: Int)Int
def g1 = g(10) _ //> g1: => Int => Int
g1(5)
The question is, Why curried required the underscore in line #5 in the second code snippet.
You can find the explanation at Martin Odersky book: http://www.artima.com/pins1ed/functions-and-closures.html (search for "Why the trailing underscore").
In short this is because Scala is closer to Java in a lot of things, rather than functional languages where this is not required. This helps you to find out mistakes at compile time, if you forgot the missing argument.
If underscore was not required, the next code will compile:
println(g(10))
And this check helps you preventing such mistakes
There are some cases though, when such calls are obvious, and underscore is not required:
def g(x: Int)(y: Int) = {
x * y
}
def d(f: Int => Int) {
f(5)
}
d(g(10)) // No need to write d(g(2) _)
// Or any other way you can specify the correct type
val p: Int => Int = g(10)
Something to note: in Scala, def's are methods, not functions, at least, not directly. Methods are converted to functions by the compiler every time a method is used where a function would be required, but strictly speaking, a function would be created with val instead, like so:
val curry = (x: Int) => (y: Int) => x * y
This allows you to apply arguments one at a time without having to add a trailing underscore. It functions identically to the code in your first snippet, but because it uses val and not def, curry cannot be written like
val curry(x: Int) = (y: Int) => x * y //Won't compile
So, when you want to write a function that behaves the way you want a curried function to behave, write it like I did in my first snippet. You can keep chaining parameters with => as many times as you want (up to technical limits, but good luck hitting them).
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.
What would be the best and/or easiest way to extract a value that I've saved in a case class?
take for example the following code:
abstract class Something
case class Foo(input: Int) extends Something
case class Bar(input: Double) extends Something
def someMethod(a: Something, b: Something) {
// code that extracts values goes here
}
someMethod(Foo(10), Foo(20))
someMethod(Bar(2.1), Bar(21.2))
how would I then go about getting the integer or the double itself out of a and b when I call the method like I did under its definition?
Note that both the parameters are used in the same equation
In case classes constructor arguments are vals, so just call:
a.input
b.input
You can also use extractor with the help of unapply method:
val Foo(val1) = a
val Bar(val2) = b
and then use val1 and val2
Update
Then you should use pattern matching on your value:
value match {
case Foo(val1) => val1
case Bar(val1) => val1
}
It works just like val Foo(val1) = a, with using generated unapply method (extractor) in your class, and it is also an expression, so you van assign the result to the variable
If you have multiple arguments just change PatMat construct according to the number of your parameters, in your case:
someMethod(a: Something, b: Something) = (a, b) match {
case (Foo(v1), Foo(v2)) => (v1, v2) // or any other logic with values
case (Foo(v1), Bar(v2)) => // logic for this case
... // logic for other cases
}
The more parameters the more cases you should provide, but you case blank cases if you don't need them
someMethod(a: Something, b: Something) = (a, b) match {
case (Foo(v1), Foo(v2)) => (v1, v2) // or any other logic with values
case _ =>
}
in this case all other cases will be ignored, not the best choice, cause the result type will be incorrect. And you also can black values
someMethod(a: Something, b: Something) = (a, b) match {
case (Foo(v1), _) => v1 // in such case you can work only with v1
... // logic for other cases
}
An alternative to pattern matching could be do redefine your classes like this:
trait Something[T]{
def input:T
}
case class Foo(input: Int) extends Something[Int]
case class Bar(input: Double) extends Something[Double]
Then, any instance of Something will expose the input property. The only potential downside is that it will be of a generic type when you access it.
The alternative approach
In addition to the direct solution of pattern matching in your method, I'll try to show a somewhat more convoluted, general and functional approach to this kind of situations. Still pattern matching is the most direct and simple answer!
If you can explicitly "certify" in your interface the input accessor, you can generalize how you work with the Something class.
In code this translates to
trait Something[T] {
def input: T
}
case class Foo(input: Int) extends Something[Int]
case class Bar(input: Double) extends Something[Double]
from here you can define how to "lift" any function you like to one that works over Somethings
Let's say you have methods that takes two inputs (e.g. Ints or Doubles) and you want to operate on such inputs within one of your case classes (i.e. Foo, Bar)
//this function lift your specific input method to one that takes Somethings
def liftSomething2[T, R](f: (T, T) => R): (Something[T], Something[T]) => R =
(a, b) => f(a.input, b.input)
Let's examine this a bit: it takes a function
(T, T) => R of 2 arguments of type T and a result R
and transforms it in a
(Something[T], Something[T]) => R which takes Somethings as arguments.
Examples
//lifts a function that sums ints
scala> val sumInts = liftSomething2[Int, Int](_ + _)
sumInts: (Something[Int], Something[Int]) => Int = <function2>
//lifts a function that multiplies ints
scala> val multInts = liftSomething2[Int, Int](_ * _)
multInts: (Something[Int], Something[Int]) => Int = <function2>
//lifts a function that divides doubles
scala> val divDbl = liftSomething2[Double, Double](_ / _)
divDbl: (Something[Double], Something[Double]) => Double = <function2>
//Now some test
scala> sumInts(Foo(1), Foo(2))
res2: Int = 3
scala> multInts(Foo(4), Foo(-3))
res3: Int = -12
scala> divDbl(Bar(20.0), Bar(3.0))
res4: Double = 6.666666666666667
//You can even complicate things a bit
scala> val stringApp = liftSomething2[Int, String](_.toString + _)
stringApp: (Something[Int], Something[Int]) => String = <function2>
scala> stringApp(Foo(1), Foo(2))
res5: String = 12
All the above examples lift functions of type (T,T) => R but the "lifting" can be made for all and any argument you need
//This takes three args of different types and returns another type
// the logic doesn't change
def liftSomething3[A,B,C,R](f: (A,B,C) => R): (Something[A], Something[B], Something[C]) => R =
(a,b,c) => f(a.input, b.input, c.input)
//sums to ints and divides by a double
scala> val sumDiv = liftSomething3[Int,Int,Double,Double]((i,j,d) => (i + j) / d)
sumDiv: (Something[Int], Something[Int], Something[Double]) => Double = <function3>
scala> sumDiv(Foo(5), Foo(30), Bar(4.2))
res7: Double = 8.333333333333332
more...
All we've seen so far should be somewhat related to category theory concepts like Applicative Functors and Comonads, but I'm no expert so I encourage you to search for yourself if you feel this sort of abstractions are useful and interesting.
In your example both the a and b have specific types: Foo and Bar respectively. That's why you can simply access their fields like so:
scala> a.input
res4: Int = 10
scala> b.input
res5: Double = 25.1
If however your value has type Something, then you'll need to pattern-match:
val input = somethingOfTypeSomething match {
case Foo(input) => input
case Bar(input) => input
}
The other answers have covered the basic scenario. There are useful variations to consider.
Constructor Pattern
As already answered there is:
value match {
case Foo(x) => x
...
}
Deep Matching
The constructor pattern also supports deep matching. For example, extract x within Bar within Foo which is 3 levels deep:
value match {
case Foo(y, Bar(x)) => x
...
}
Variable Binding
If the value you want to extract is an actual case class inside another case class you can use variable binding. E.g. to extract the whole Bar(x) into b:
value match {
case Foo(y, b # Bar(x)) => b
...
}
Programming in Scala by M. Odersky, Spoon and Venners has a great chapter on case classes and pattern matching which covers many other scenarios. Pattern matching is such a rich part of the language it would be a worthwhile investment.
Is there a syntax to allow generic type parameters on function literals? I know I could wrap it in a method such as:
def createLongStringFunction[T](): (T) => Boolean = {
(obj: T) => obj.toString.length > 7
}
but then I end up needing to invoke the method for every type T and getting a new function. I looked through the language reference, and while I see that the function literal syntax is translated by the compiler to an instance of a Functionn object that itself has generic input types, it looks like the compiler magic realizes those parameters at the time of creation. I haven't found any syntax that allows me to, in effect, "leave one or more of the type parameters of Functionn unbound". What I would prefer is something along the lines of:
// doesn't compile
val longStringFunction: [T](T) => Boolean = (obj: T) => obj.toString.length > 7
Does any such thing exist? Or for that matter, what is the explicit type of an eta-expansion function when the method being expanded has generic parameters?
This is a purely contrived and useless example. Of course I could just make the function use Any here.
No, type parameters only apply to methods and not function objects. For example,
def f[T](x: T) = x //> f: [T](x: T)T
val g = f _ //> g: Nothing => Nothing = <function1>
// g(2) // error
val h: Int=>Int = f _ //> h : Int => Int = <function2>
h(2) //> res0: Int = 2
The method f cannot be converted to a polymorphic function object g. As you can see, the inferred type of g is actually Function1[Nothing, Nothing], which is useless. However, with a type hint we can construct h: Function1[Int,Int] that works as expected for Int argument.
As you say, in your example all you're requiring is the toString method and so Any would be the usual solution. However, there is call for being able to use higher-rank types in situations such as applying a type constructor such as List to every element in a tuple.
As the other answers have mentioned, there's no direct support for this, but there's a relatively nice way to encode it:
trait ~>[A[_],B[_]] {
def apply[X](a : A[X]) : B[X]
}
type Id[A] = A //necessary hack
object newList extends (Id ~> List) {
def apply[X](a : Id[X]) = List(a)
}
def tupleize[A,B, F[_]](f : Id ~> F, a : A, b : B) = (f(a), f(b))
tupleize(newList, 1, "Hello") // (List(1), List(Hello))
Since longStringFunction defined as followed is a value, which must have some given type.
val longStringFunction: (T) => Boolean = (obj: T) => obj.toString.length > 7
However, you can reuse a function object with a method:
scala> val funObj: Any => Boolean = _.toString.size > 7
funObj: Any => Boolean = <function1>
scala> def typedFunction[T]: T => Boolean = funObj
typedFunction: [T]=> T => Boolean
scala> val f1 = typedFunction[String]
f1: String => Boolean = <function1>
scala> val f2 = typedFunction[Int]
f2: Int => Boolean = <function1>
scala> f1 eq f2
res0: Boolean = true
This works because trait Function1[-T1, +R] is contravariant of type T1.
In scala, Function values are parametrically monomorphic(while methods are polymorphic)
Shapeless library introduces polymorphic function values which may be mapped over HLists and many more other features.
Please consider the following refs:
http://www.chuusai.com/2012/04/27/shapeless-polymorphic-function-values-1/
http://www.chuusai.com/2012/05/10/shapeless-polymorphic-function-values-2/