Somewhat similar to Stack Overflow question Compose and andThen methods, I've been working through Twitter's Scala School tutorial and quickly ran into the same problem that a commenter had (which was great, because I went to bed thinking my problem was solved).
In the tutorial, it defines two methods as such:
def addUmm(x: String) = x + " umm"
def addAhem(x: String) = x + " ahem"
and while in newer versions of Scala, you can't call compose on them as such: addUmm(_).compose(addAhem(_)), the accepted answer (and some of the other answers seem to hinge upon the fact that addUmm and addAhem are methods, not functions, which creates an issue when trying to call compose. I went to bed satisfied, having successfully run:
scala> ((s: String) => s + " umm").compose((s: String) => s + " ahem")
res0: String => java.lang.String = <function1>
Cool. The issue is that while not being able to compose methods makes some sense, when I the same thing with values I know evaluate to Function1:
val a = (s: String) => s + " umm"
val b = (s: String) => s + " ahem"
val c = a(_).compose(b(_))
Well, that last line coughs up the same error that the original question did, even though they're partial applications of functions this time, not methods. One of the answers in the original question (highly-ranked, but not the accepted answer) seems to hint that it has to do with how the partial application is expanded, what is the explanation?
For a Scala newbie, the fact that the inferencer gets a(_).compose(b(_)) wrong no matter if you explicitly specify _: String both places, but a.compose(b) does is somewhat confusing.
a(_).compose(b(_)) expands to x => { a(x).compose(y => b(y) }. Hence the error. What you want is (x => a(x)).compose(y => b(y)). Adding a pair of parentheses fixes this.
scala> (a(_)).compose(b(_: String))
res56: String => java.lang.String = <function1>
scala> res56("hello")
res57: java.lang.String = helloahemumm
But since a and b are functions, you can avoid all this cruft and simply do a compose b.
You can use simply 'a compose b'.
scala> val c = a compose b
c: String => java.lang.String = <function1>
Related
I'm currently doing a Scala course and recently I was introduced to different techniques of returning functions.
For example, given this function and method:
val simpleAddFunction = (x: Int, y: Int) => x + y
def simpleAddMethod(x: Int, y: Int) = x + y
I can return another function just doing this:
val add7_v1 = (x: Int) => simpleAddFunction(x, 7)
val add7_v2 = simpleAddFunction(_: Int, 7)
val add7_v3 = (x: Int) => simpleAddMethod(x, 7)
val add7_v4 = simpleAddMethod(_: Int, 7)
All the values add7_x accomplish the same thing, so, whats the purpose of Currying then?
Why I have to write def simpleCurryMethod(x: Int)(y: Int) = x + y if all of the above functions do a similar functionality?
That's it! I'm a newbie in functional programming and I don't know many use cases of Currying apart from saving time by reducing the use of parameters repeatedly. So, if someone could explain me the advantages of currying over the previous examples or in Currying in general I would be very grateful.
That's it, have a nice day!
In Scala 2 there are only four pragmatic reasons for currying METHODS (as far as I can recall, if someone has another valid use case then please let me know).
(and probably the principal reason to use it) to drive type inference.
For example, when you want to accept a function or another kind of generic value whose generic type should be inferred from some plain data. For example:
def applyTwice[A](a: A)(f: A => A): A = f(f(a))
applyTwice(10)(_ + 1) // Here the compiler is able to infer that f is Int => Int
In the above example, if I wouldn't have curried the function then I would need to have done something like: applyTwice(10, (x: Int) => x + 1) to call the function.
Which is redundant and looks worse (IMHO).
Note: In Scala 3 type inference is improved thus this reason is not longer valid there.
(and probably the main reason now in Scala 3) for the UX of callers.
For example, if you expect an argument to be a function or a block it is usually better as a single argument in its own (and last) parameter list so it looks nice in usage. For example:
def iterN(n: Int)(body: => Unit): Unit =
if (n > 0) {
body
iterN(n - 1)(body)
}
iterN(3) {
println("Hello")
// more code
println("World")
}
Again, if I wouldn't have curried the previous method the usage would have been like this:
iterN(3, {
println("Hello")
// more code
println("World")
})
Which doesn't look that nice :)
(in my experience weird but valid) when you know that majority of users will call it partially to return a function.
Because val baz = foo(bar) _ looks better than val baz = foo(bar, _) and with the first one, you sometimes don't the the underscore like: data.map(foo(bar))
Note: Disclaimer, I personally think that if this is the case, is better to just return a function right away instead of currying.
Edit
Thanks to #jwvh for pointing out this fourth use case.
(useful when using path-dependant types) when you need to refer to previous parameters. For example:
trait Foo {
type I
def bar(i: I): Baz
}
def run(foo: Foo)(i: foo.I): Baz =
foo.bar(i)
As part of my learning, I am trying to write the Scala expression into a scala script but struck with an error.
The scala code I am having it successfully executed in Scala REPL is
def intList = List[1,2,3,4,5]
intList.filter(x => x%2 ==1).map(x => x * x).reduce((x,y) => x+y)
This successfully gets executed and the following is the result I get.
scala> intList.filter(x => x % 2 == 1).map(x => x * x).reduce((x,y) => x + y)
res15: Int = 35
I am trying to make this as a Scala script or class so as to rerun any number of times on demand. I save this in a file named SumOfSquaresOfOdd.scala
import scala.collection.immutable.List
object SumOfSquaresOfOdd extends App
{
def main(args:Array[String]):Unit =
{
var intList = List[Integer](1,2,3,4,5,6,7,8,9,10)
def sum = intList.filter(x => x % 2 ==1).map(x => x * x).reduce((x+y) => x + y)
println sum
}
}
When I compile this using scalac, the following error is printed on the console.
λ scalac SumOfSquaresOfOdd.scala
SumOfSquaresOfOdd.scala:8: error: not a legal formal parameter.
Note: Tuples cannot be directly destructured in method or function parameters.
Either create a single parameter accepting the Tuple1,
or consider a pattern matching anonymous function: `{ case (param1, param1) => ... }
def sum = intList.reduce(x => x % 2 ==1).map(x => x * x).reduce((x+y) => x + y)
^
one error found
How do I use the filter, map, reduce methods in a script? Appreciate your help and support.
UPDATE: Typos updated in the code.
I can answer your question:
How do I use the filter, map, reduce methods in a script?
But I can't fully solve your specific use case because you didn't specify what the script should be doing.
Try this code
object SumOfSquaresOfOdd {
def main(args: Array[String]) : Unit = {
var intList = List(1,2,3,4,5,6,7,8,9,10)
def sum = intList.filter(x => x % 2 ==1).map(x => x * x)
println(sum)
}
}
Then
~/Code/stack-overflow $ scalac SumOfSquaresOfOdd.scala
~/Code/stack-overflow $ scala SumOfSquaresOfOdd
List(1, 9, 25, 49, 81)
You seem to be a little lost. Here are some tips:
Use Int rather than Integer; Int is Scala's integer type. And you don't need to import it.
Don't extend App in this case. Refer to this question Difference between using App trait and main method in scala
Use wrapping parens for println
A literal List(1,2,3) will be type-inferenced to List[Int]; no need to explicitly type it. Check in the Scala REPL.
I think you confused reduce with filter. Compare both in the latest scaladoc: http://www.scala-lang.org/api/current/#scala.collection.immutable.List
Other ways to run scala code: http://joelabrahamsson.com/learning-scala-part-three-executing-scala-code/
Highly recommend you do Functional Programming Principles in Scala if you're serious about learning.
Good luck learning Scala! :)
I know the function vs. method discussions are well beat up on, so I will try to be brief. I am looking to show a tiny block of code and get feedback on:
Is it a method, function, both, or something else?
If it be a method, can it be made into a function? (other than by val f = m _)
Are there more idiomatic ways to do what I'm trying in this example?
When I see docs for methods we see the following:
def m(a:Int, b:Int):Int = { a + b }
Looking for functions we see:
(a:Int, b:Int) => a + b OR
val f:(Int,Int) => Int = (a, b) => a + b
However, when we poke around for recursive functions we nearly always see:
#tailrec def countStrings(a:List[String], b:Int = 0):Int = {
if (a == Nil) b
else countStrings(a.tail, b + 1)
}
countStrings: (a: List[String], b: Int)Int
So, based on all that I've read about methods the above recursive string counter is a recursive method - not a function. Now, if we re-write this as a function according to how the docs tell us to write functions:
val countStrings:(List[String],Int) => Int = (a,b) => {
if (a == Nil) b
else countStrings(a.tail, b + 1)
}
countStrings: (List[String], Int) => Int = <function2>
So my question is precisely this: Is the following block annotated with #tailrec a function, a method, both, or something else?
#tailrec def countStrings(a:List[String], b:Int = 0):Int = {
if (a == Nil) b
else countStrings(a.tail, b + 1)
}
Also, apologies if this is a duplicate, I have searched and, as with most things scala, have found conflicting opinions on this matter. So my hope is to put forth an extremely simple example and get a definitive answer. Thank you.
Your tailrec example is called a method in scala and tailrec annotation could be applied to a method, not to a function.
On the other hand your function implementation looks also correct achieving the same result, but you cannot annotate it to benefit from the compiler tail recursion check.
As you mentioned in your question, you can still convert your method to a function like this:
scala> countStrings _
res0: (List[String], Int) => Int = <function2>
Being precise, the example case #tailrec def countStrings... is a method - not a function. While conversion to a function or writing as a function is possible the syntax in question can only properly be called a method.
I'm learning specs2 testing framework by following some of its examples.
I've noticed the following anonymous function syntax is recurring:
val upper = (_: String).toUpperCase
which is equivalent to more conventional / usual
val upper = (s: String) => s.toUpperCase
Although the syntax is simple and elegant, yet it's not very familiar (easy).
Can someone step me through how the first syntax works / derives? I'm pretty sure that it has to do with some sort of partial application but cannot reason fully.
Also is the syntax used frequently in Scala? (I'm still learning the ropes here :] )
Edit::
I've found the recurring pattern to use such syntax is with ad-hoc polymorphism (simply, overloaded methods / functions) where argument type of the passed function determines what function is dispatched.
For example,
def f(g: Int => String): String = g(10)
def f(g: String => String): String = g("hello")
f((_: Int).toString + " beers") // 10 beers
f((_: String) + " world") // hello world
This kind of pattern is recurring in libraries like ScalaCheck.
The syntax indicates the compiler you're creating a function with a parameter of type String, which is inserted where the _ is used, according to parameter order. If you had:
val f = (_:String).length + (_:Int)
it would create a function (String, Int) => Int, where each _ marks where the parameter is being used. The order is important! They must be used in the same order you want the function's parameters to be
If the types are already defined when declaring the val, you can omit them in the function body:
val f: (String, Int) => Int = _.length + _
Sorry for the nebulous title, I had a hard time to to formulate what I mean. For that reason, lets directly dive into the code:
def bar(b: Int => String) = b(23)
def foo(b: => String) = bar(_ => b)
foo("foo" + "bar")
I found a similar code in the play framework and was wondering what actually happens with that code. I tinkered a bit and figured that bar(_ => b) will just create a function1 with the required argument type (given by bars signature) and uses the given function0 to generate the return value, ignoring the actual parameter of the function1.
However, this is just me trying to figure out what happens, a more definitive answer would be way better for my understanding - and besides that I might be completely wrong.
You're sort of right, except that => String is not a Function0 - () => String is.
=> String is a call-by-name string. It'll be evaluated when it's referred to.
def foo(b: String) = bar(_ => b) would also get the job done, with the exception that b would be evaluated eagerly.