Scala define function standard - function

The following are equivalent:
scala> val f1 = {i: Int => i == 1}
f1: Int => Boolean = <function1>
scala> val f2 = (i: Int) => i == 1
f2: Int => Boolean = <function1>
I am more familiar with the former (coming from Groovy), but the latter form is much more common, AFAIK, the standard way to define a function in Scala.
Should I forget the past (Groovy) and adopt the 2nd form? The 1st form is more natural for me as it looks similar to Groovy/Ruby/Javascript way of defining closures (functions)
EDIT
See Zeiger's answer in this thread, for an example where groovy/ruby/javascript closure {=>} syntax seems more natural than () => I assume both can be used interchangeably with same performance, ability to pass around, etc. and that the only difference is syntax

I think that this is the matter of taste (scala styleguide recommends first one). The former one allow you to write multiline (>2 lines in body) functions:
val f1 = { i: Int =>
val j = i/2
j == 1
}
Sometimes it is useful

Actually, both versions are simplified forms of the "full" version.
Full version: multiple parameters, multiple statements.
scala> val f0 = { (x: Int, y: Int) => val rest = x % y; x / y + (if (rest > 0) 1 else 0) }
f0: (Int, Int) => Int = <function2>
The "groovy" version: one parameter, multiple statements.
scala> val f1 = { x: Int => val square = x * x; square + x }
f1: Int => Int = <function1>
The "scala" version: multiple parameters, one statement.
scala> val f2 = (x: Int, y: Int) => x * y
f2: (Int, Int) => Int = <function2>
A version with a single parameter and a single statement does not exist, because it is not syntactically valid (ie, the grammar for that doesn't quite work).

Related

3? ways in scala to return a function from a function - 1 doesn't compile - don't understand why

I'm learning Scala. I have a Scala function which can return another function. I've come across 3 ways to do this in Scala (there may be more). In this particular code the 3rd option doesn't seem to compile but I've seen this technique used elsewhere but can't work out why it isn't working in this case.
In this fairly contrived example I have a function that takes an Int and returns a function that maps an Int to Boolean.
def intMapper1(elem: Int): Int => Boolean = {
def mapper(x: Int): Boolean =
x == elem
mapper
}
def intMapper2(elem: Int): Int => Boolean = (x: Int) => x == elem
def intMapper3(elem: Int)(x: Int) = x == elem
val m1 = intMapper1(2)
val m2 = intMapper2(4)
val m3 = intMapper3(6)
I get the compile error:
Error:(35, 22) missing arguments for method intMapper3 in object FunSets;
follow this method with `_' if you want to treat it as a partially applied function
val m3 = intMapper3(6)
^
The method def intMapper3(elem: Int)(x: Int) = x == elem has two parameter list, you are passing only one parameter(i.e. elem), the second parameter (x) is missing here. And intMapper3 is not a higher order function. It is not taking any function as argument and not returning a function. It is a normal method, taking two parameter list and returns a Boolean value.
You can derive a partially applied function from m3 as val m3 = intMapper3(6)_. That is what compiler telling you.
Your Method def intMapper3(elem: Int)(x: Int) = x == elem is a simple function in scala. it takes two parameters "elem" and "x" and computes the result.
It can be used as :
scala> intMapper3(2)(2)
res2: Boolean = true
scala> intMapper3(2)(1)
res3: Boolean = false
But if you pass only one argument it will show an error because intMapper3 requires two parameters.
"intMapper1" function can be called in these following ways:
scala> intMapper1(1)(2)
res0: Boolean = false
scala> intMapper1(1)(1)
res1: Boolean = true
In this case the output of "intMapper1" is a function that takes and argument of Int type and returns a boolean result.
scala> val m1 = intMapper1(2)
m1: Int => Boolean = <function1>
scala> m1(2)
res1: Boolean = true

Scala: Anonymous function return type

Why do i have to declare the return type this way:
def main(args: Array[String]): Unit = {
val n = (x: Int) => (1 to x) product: Int
println(n(5))
}
If i remove the type, i'd have to assign it before printing:
def main(args: Array[String]): Unit = {
val n = (x: Int) => (1 to x) product
val a = n(5)
println(n(5))
}
this variant gives an error - why?
val n = (x: Int) => (1 to x) product
println(n(5))
I get the following error (using Scala-ide):
recursive value n needs type Test.scala /src line 5 Scala Problem
You are seeing a problem with semicolon inference, due to the use of a postfix operator (product):
// Error
val n = (x: Int) => (1 to x) product
println(n(5))
// OK - explicit semicolon
val n = (x: Int) => (1 to x) product;
println(n(5))
// OK - explicit method call instead of postfix - I prefer this one
val n = (x: Int) => (1 to x).product
println(n(5))
// OK - note the newline, but I wouldn't recommend this solution!
val n = (x: Int) => (1 to x) product
println(n(5))
Essentially, Scala gets confused as to where an expression ends, so you need to be a little more explicit, one way or another.
Depending on compiler settings, this feature may be disabled by default - see Scala's "postfix ops" and SIP-18: Modularizing Language Features

Scala implicit function parameterized

Why would this code not take the implicit functions defined in the local scope?
From where else does this take the implicit functions?
def implctest[T](a: T)(implicit b:T=>T):T = {b apply a}
class Testimplcl(val a:Int){
override def toString() = "value of the 'a' is = "+a
}
implicit def dble(x: Int):Int = {x + x}
implicit def stringer(x: String):String = {x+" no not a pity"}
implicit def myclass(x: Testimplcl):Testimplcl = new Testimplcl(x.a +1)
implctest[String]("oh what a pity")
implctest[Int](5)
implctest[Testimplcl](new Testimplcl(4))
None of my implicit defs in local scope are taken in.
For eg the implctestInt gives result 5, I expect it to return 10 by taking the dble as implicit.
It does not show error also. implctest simply returns the arguments passed in.
When you ask for a function A => A, Scala provides an implicit lift from a method definition, such as
implicit def dble(x: Int):Int = x + x
That is, it will treat that as a function dble _. So in the implicit resolution, this is not an immediately available value.
The problem you have is that there is an implicit A => A for any type, defined as Predef.conforms:
def conforms[A]: <:<[A, A] // where <:< is a sub class of A => A
This is useful and necessary because whenever you want a view from A => B and A happens to be B, such a "conversion" is automatically available.
See, with a direct function:
implicit val dble = (x: Int) => x + x
You see the conflict:
implicitly[Int => Int] // look for an implicit conversion of that type
<console>:49: error: ambiguous implicit values:
both method conforms in object Predef of type [A]=> <:<[A,A]
and value dble of type => Int => Int
match expected type Int => Int
implicitly[Int => Int]
^
So, in short, it's not good to ask for a custom A => A. If you really need such thing, use a custom type class such as Foo[A] extends (A => A).
If you will rewrite your implicits like ths:
implicit val dble = (x: Int) => x + x
implicit val stringer = (x: String) => x + " no not a pity"
implicit val myclass = (x: Testimplcl) => new Testimplcl(x.a +1)
then you will immediately see the reason for this behavior. Now you have the problem with ambiguous implicit values:
scala: ambiguous implicit values:
both method conforms in object Predef of type [A]=> <:<[A,A]
and value stringer in object ReflectionTest of type => String => String
match expected type String => String
println(implctest[String]("oh what a pity"))
^
This generally tells you that Predef already defined an implicit function T => T, so it conflicts with your definitions.
I will recommend you not to use such general types as Function as implicit parameters. Just create your own type for this. Like in this example:
trait MyTransformer[T] extends (T => T)
object MyTransformer {
def apply[T](fn: T => T) = new MyTransformer[T] {
def apply(v: T) = fn(v)
}
}
def implctest[T: MyTransformer](a: T): T =
implicitly[MyTransformer[T]] apply a
class Testimplcl(val a:Int){
override def toString() = "value of the 'a' is = "+a
}
implicit val dble = MyTransformer((x: Int) => x + x)
implicit val stringer = MyTransformer((x: String) => x + " no not a pity")
implicit val myclass = MyTransformer((x: Testimplcl) => new Testimplcl(x.a +1))

When do I have to treat my methods as partially applied functions in Scala?

I noticed that when I'm working with functions that expect other functions as parameters, I can sometimes do this:
someFunction(firstParam,anotherFunction)
But other times, the compiler is giving me an error, telling me that I should write a function like this, in order for it to treat it as a partially applied function:
someFunction(firstParam,anotherFunction _)
For example, if I have this:
object Whatever {
def meth1(params:Array[Int]) = ...
def meth2(params:Array[Int]) = ...
}
import Whatever._
val callbacks = Array(meth1 _,meth2 _)
Why can't I have the code like the following:
val callbacks = Array(meth1,meth2)
Under what circumstances will the compiler tell me to add _?
The rule is actually simple: you have to write the _ whenever the compiler is not explicitly expecting a Function object.
Example in the REPL:
scala> def f(i: Int) = i
f: (i: Int)Int
scala> val g = f
<console>:6: error: missing arguments for method f in object $iw;
follow this method with `_' if you want to treat it as a partially applied function
val g = f
^
scala> val g: Int => Int = f
g: (Int) => Int = <function1>
In Scala a method is not a function. The compiler can convert a method implicitly in a function, but it need to know which kind. So either you use the _ to convert it explicitly or you can give some indications about which function type to use:
object Whatever {
def meth1(params:Array[Int]): Int = ...
def meth2(params:Array[Int]): Int = ...
}
import Whatever._
val callbacks = Array[ Array[Int] => Int ]( meth1, meth2 )
or:
val callbacks: Array[ Array[Int] => Int ] = Array( meth1, meth2 )
In addition to what Jean-Philippe Pellet said, you can use partially applied functions, when writing delegate classes:
class ThirdPartyAPI{
def f(a: Int, b: String, c: Int) = ...
// lots of other methods
}
// You want to hide all the unnecessary methods
class APIWrapper(r: ThirdPartyAPI) {
// instead of writing this
def f(a: Int, b: String, c: Int) = r.f(a, b, c)
// you can write this
def f(a: Int, b: String, c: Int) = r.f _
// or even this
def f = r.f _
}
EDIT added the def f = r.f _ part.

How can I obtain Function objects from methods in Scala?

Suppose I have a simple class in Scala:
class Simple {
def doit(a: String): Int = 42
}
How can I store in a val the Function2[Simple, String, Int] that takes two arguments (the target Simple object, the String argument), and can call doit() get me the result back?
val f: Function2[Simple, String, Int] = _.doit(_)
same as sepp2k, just using another syntax
val f = (s:Simple, str:String) => s.doit(str)
For those among you that don't enjoy typing types:
scala> val f = (_: Simple).doit _
f: (Simple) => (String) => Int = <function1>
Following a method by _ works for for any arity:
scala> trait Complex {
| def doit(a: String, b: Int): Boolean
| }
defined trait Complex
scala> val f = (_: Complex).doit _
f: (Complex) => (String, Int) => Boolean = <function1>
This is covered by a combination of §6.23 "Placeholder Syntax for Anonymous Functions" and §7.1 "Method Values" of the Scala Reference