Where do you split long Scala function signatures? - scala

A definition like
def foo(x: Int) = x + 1
is nice and short and looks pretty, but when the signature itself gets uncomfortably long,
def foo[T <: Token[T]](x: ArrayBuffer[T], y: T => ArrayBuffer[() => T]): (T, T, BigDecimal) = {
// ...
}
I don't know where to split it. I find all of the following to look awkward:
def foo(
x: Int,
y: Int
): Int = {
// ...
}
def foo(
x: Int,
y: Int
): Int =
{
// ...
}
def foo(
x: Int,
y: Int
): Int
= {
// ...
}
def foo(
x: Int,
y: Int
):
Int = {
// ...
}
But, given that I'm going to have to get used to one of these, which will cause the least annoyance to my teammates?

The Scala style guide has nothing to say on this. In fact it recommends using methods with fewer parameters :-).
For function invocations it does recommend splitting so that each subsequent line aligns with the first parenthesis:
foo(someVeryLongFieldName,
andAnotherVeryLongFieldName,
"this is a string",
3.1415)
Personally in your case I would split according to a 'keep like things together' rule:
def foo[T <: Token[T]]
(x: ArrayBuffer[T], y: T => ArrayBuffer[() => T])
: (T, T, BigDecimal) = {
// ...
}
So the parameters are on one line, the return type is on a single line and the type restriction is on a single line.

In Haskell, long type signatures are often written in this fashion:
someFunc :: (Some Constraints Go Here)
=> Really Long Arg1 Type
-> Really Long Arg2 Type
-> Really Long Result Type
somefunc x y = ...
To translate this Haskellism into Scala,
def foo [ T <: Token[T] ]
( x : ArrayBuffer[T]
, y : T => ArrayBuffer[() => T]
) : (T, T, BigDecimal) = {
// ...
}
That's how I would do it. Not sure how kosher it is with the Scala community.

Related

High order functions in Scala

IM trying to understand the below high order functions in Scala but need some clarifications on the parameters of the functions.
Questions:-
What does the Int => String in the apply function mean?
v: Int indicates that the parameter v is of type Int.
What does the [A](x: A) mean in layout function?
object Demo {
def main(args: Array[String]) {
println( apply( layout, 10) )
}
def apply(f: Int => String, v: Int) = f(v)
def layout[A](x: A) = "[" + x.toString() + "]"
}
f: Int => String means that f is a function with one argument of type Int and with a return type String
def layout[A](x: A) means that parameter x is of type A, which can be of any type. Here are a couple of examples on how to invoke layout:
layout[String]("abc") //returns "[abc]"
layout[Int](123) //returns "[123]"
When main runs it invokes apply with the layout function and the argument 10. This will output "[10]"
The syntax of Int => String means passing a function that accepts Int and returns String.
Here is a useful example for passing function:
case class Person(name: String, lastName: String)
val person = Person("Johnny", "Cage")
def updateName(name: String) = {
updatePerson(_.copy(name = name))
}
def updateLastName(lastName: String) {
updatePerson(_.copy(lastName = lastName))
}
private def updatePerson(transformer: Person => Person): Unit = {
transformer(person)
}
Note how each update function passes the copy constructor.

generic type-based function to sum numbers based on their types

Suppose x and y are of the same type and can be either Boolean, Int, or Double. Here is the function I want to write:
f(x, y) =
- if x == Boolean ==> !x
- if x == Integer or x == Double ==> x+ y
One way of doing this can be the following. I was wondering if anyone has a better ideas on this.
def fun[T](x: T, y: T): T {
x match {
case xP: Boolean => !xP
case xP: Double => y match { case yP: Double => xP + yP }
case xP: Int => y match { case yP: Int => xP + yP }
}
}
The reason I am not happy with this is that x and y have the same type. I shouldn't need two match-cases; right?
Two other things:
Is it enough to just set [T <: Int, Double, Boolean] in order to restrict the type to only three types?
The output type needs to be again T.
This is precisely the kind of problem that type classes are designed to solve. In your case you could write something like this:
trait Add[A] {
def apply(a: A, b: A): A
}
object Add {
implicit val booleanAdd: Add[Boolean] = new Add[Boolean] {
def apply(a: Boolean, b: Boolean): Boolean = !a
}
implicit def numericAdd[A: Numeric]: Add[A] = new Add[A] {
def apply(a: A, b: A): A = implicitly[Numeric[A]].plus(a, b)
}
}
A value of type Add[X] describes how to add two values of type X. You put implicit "instances" of type Add[X] in scope for every type X that you want to be able to perform this operation on. In this case I've provided instances for Boolean and any type that has an instance of scala.math.Numeric (a type class that's provided by the standard library). If you only wanted instances for Int and Double, you could simply leave out numericAdd and write your own Add[Int] and Add[Double] instances.
You'd write your fun like this:
def fun[T: Add](x: T, y: T) = implicitly[Add[T]].apply(x, y)
And use it like this:
scala> fun(true, false)
res0: Boolean = false
scala> fun(1, 2)
res1: Int = 3
scala> fun(0.01, 1.01)
res2: Double = 1.02
This has the very significant advantage of not blowing up at runtime on types that you haven't defined the operation for. Instead of crashing your program with a MatchError exception when you pass e.g. two strings to fun, you get a nice compilation failure:
scala> fun("a", "b")
<console>:14: error: could not find implicit value for evidence parameter of type Add[String]
fun("a", "b")
^
In general "type case" matching (i.e. matches that look like case x: X => ...) are a bad idea in Scala, and there's almost always a better solution. Often it'll involve type classes.
If you want a generic function for summing numbers, you can make a trait Summable[A] with implicit conversions from the numbers you want to Summable. These conversions can be implicit methods or they can be methods in implicit objects, latter being shown below.
trait Summable[A] {
def +(a: A, b: A): A
}
object Summable {
implicit object SummableBoolean extends Summable[Boolean] {
override def +(a: Boolean, b: Boolean) = !a
}
implicit object SummableInt extends Summable[Int] {
override def +(a: Int, b: Int) = a + b
}
implicit object SummableDouble extends Summable[Double] {
override def +(a: Double, b: Double) = a + b
}
}
def fun[A](a: A, b: A)(implicit ev: Summable[A]) =
ev.+(a, b)
val res1 = fun(true, true) // returns false
val res2 = fun(1, 3) // returns 4
val res3 = fun(1.5, 4.3) // returns "5.8"
This is called a type class pattern. I included the boolean case because you asked for it, but I strongly believe that it has no place in a function which sums elements. One nice rule to follow is to have each function do one thing and one thing only. Then you can easily compose them into bigger functions. Inverting boolean has no place in a function that sums its arguments.
First of all, your example is syntactically wrong (missing case in match). A simple and shorter way I can figure now is something like this:
def fun[T <: AnyVal](x: T, y: T) = {
x match {
case xP: Boolean => !xP
case xP: Double => xP + y.asInstanceOf[Double]
case xP: Int => xP + y.asInstanceOf[Int]
}
}
fun(1, 2) // res0: AnyVal = 3
fun(2.5, 2.6) // res1: AnyVal = 5.1
fun(true, false) // res2: AnyVal = false

Why should calling a currying function with non-complete args with underscore

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).

What is the purpose of outer and inner function parameters in Scala?

In the following code:
def product(f: Int => Int)(a:Int, b:Int): Int =
if (a > b) 1
else f(a) * product(f)(a + 1, b)
The parameters a and b are passed to the inner function, but you could write exactly the same function definition like so:
def product(f: Int => Int, a:Int, b:Int): Int =
if (a > b) 1
else f(a) * product(f, a + 1, b)
So what is the purpose of separating the parameters? In other words, why do this:
(f: Int => Int)(a:Int, b:Int)
when you can more clearly write:
(f: Int => Int, a:Int, b:Int)
Another feature of multiple parameters lists is partial application:
def sum3(a: Int)(b: Int)(c: Int): Int = a + b + c
val g: Int => Int => Int = sum3(10) _
val h: Int => Int = g(20)
val r: Int = h(30) // 10 + 20 + 30 = 60
You can partially apply a function and obtain another function which is equivalent to the original one but with one of the arguments fixed. _ after sum3(10) is needed because sum3 is a method, not a function, and _ converts methods to functions.
This is very useful when you are using higher-order functions:
def adder(x: Int)(y: Int) = x + y
Seq(1, 2, 3, 4) map adder(10) // Seq(11, 12, 13, 14)
When partially applied method/function is used as an argument of a higher-order call, _ is not needed, and the syntax becomes very succinct.
Another use case of this feature is that if you want to create a control structure that looks like it's built into Scala programming language itself.
For example, I could write an control structure named times which help me execute the code block exactly n times by the following method definition:
// since block is call by name, it will not be evaluate when you call it.
def times(n: Int)(block: => Any): Unit = {
for (i <- 0 until n) {
block // evaluate(execute) block
}
}
// Now I can use the times method like a control structure
times(5) {
println("Hello World");
}
It depends whether there is implicit parameter (which can't be properly mixed with plain ones)...
def foo(i: Int)(implicit p: P): Foo
... and the way you want to call it ...
def foo1(a: Int)(b: Int => Boolean): Boolean
foo1(9) { i => false }
def foo2(a: Int, b: Int => Boolean): Boolean
foo2(9, { i => false })

Swappable Trait in Scala

I want to define a Swappable trait with two values x,y and a swap method such that calling swap on an object inheriting from Swappable returns another object of the same type with x,y switched. My best so far is:
trait Swappable[T] {
val x: T
val y: T
def swap: Swappable[T] = {
val (a,b) = (x,y)
new Swappable[T] { val x=b; val y=a }
}
}
But this isn't what I want because the return type of swap is some anonymous class, instead of the original class I started with, so I get errors like:
def direct[S<:Swappable[Int]](s: S): S = if (s.x > s.y) s else s.swap
<console>:32: error: type mismatch;
found : Swappable[Int]
required: S
def direct[S<:Swappable[Int]](s: S): S = if (s.x > s.y) s else s.swap
^
Is it possible to do what I'm trying to do? What is the correct type signature for swap?
I don't know how to do it, but I think maybe it would help to get a better idea of what exactly you want to happen. Consider a class like
case class Foo(x: Int, y: Int) extends Swappable[Int] {
val z = x
}
Now, if you have f = Foo(1, 2), should f.swap give you a Foo where x != z? If so, there's no way within Scala to create a Foo like that. If not, what does it really mean to "swap x and y"?
Perhaps what you're really looking for is something like this:
trait Swappable[A,T] {
this: A =>
val x: T
val y: T
def cons(x: T, y: T): A
def swap = cons(y, x)
}
case class Foo(x: Int, y: Int) extends Swappable[Foo,Int] {
val z = x
def cons(x: Int, y: Int) = copy(x=x, y=y)
}
But I'm not sure.
What about something like that:
trait Swappable[T] {
type A
val x: T
val y: T
def create(a: T, b: T): A
def swap = create(y, x)
}
case MySwappable[T](x: T, y: T) extends Swappable[T] {
type A = MySwappable
def create(a: T, b: T) = MySwappable(a, b)
}