I have the following class definition and list
class myclass{
val val1: Int = 1
val val2: Int = 2
...
}
val mylist = List(a: myclass, b: myclass, c: myclass, d: myclass)
How can I convert the next line of code to underscore notation
mylist.foldLeft(0)((x,y) => x + y.val1 * y.val2)
I know that the next line doesn't work:
(0 /: mylist)(_ + _.val1 * _.val2)
This is because the first _ is refered to x and the second is referred to y, but the third _ scala doesn't know which variable is referred, my question is if there is a way that this works
This isn't too crazy:
scala> case class C(v: Int, w: Int)
defined class C
scala> val cs = List(C(1,2),C(3,4))
cs: List[C] = List(C(1,2), C(3,4))
scala> cs.iterator.map(c => c.v*c.w).foldLeft(0)(_+_)
res0: Int = 14
It expresses that the operations are independent. Iterating avoids an intermediate list.
Related
I have a template using a valueObject that might be one of two flavours depending on where it is used in our app. So I am importing it as an Either:
valueObject: Either[ ObjectA, ObjectB ]
Both objects have an identically named property on them so I would like to retrieve it just by calling
valueObject.propertyA
Which doesn't work.
What is the most concise/ best way of doing this?
Assuming the two objects have the same type (or a supertype / trait) that defines that property - you can use merge which returns left if it exists and right otherwise, with the lowest common type of both:
scala> class MyClass {
| def propertyA = 1
| }
defined class MyClass
scala> val e1: Either[MyClass, MyClass] = Left(new MyClass)
e1: Either[MyClass,MyClass] = Left(MyClass#1e51abf)
scala> val e2: Either[MyClass, MyClass] = Right(new MyClass)
e2: Either[MyClass,MyClass] = Right(MyClass#b4c6d0)
scala> e1.merge.propertyA
res0: Int = 1
scala> e2.merge.propertyA
res1: Int = 1
Using fold
Assuming the two objects do not share a common supertype that holds the property/method, then you have to resort to fold:
scala> case class A(a: Int)
defined class A
scala> case class B(a: Int)
defined class B
scala> def foldAB(eab: Either[A,B]): Int = eab.fold(_.a,_.a)
foldAB: (eab: Either[A,B])Int
scala> foldAB(Left(A(1)))
res1: Int = 1
scala> foldAB(Right(B(1)))
res2: Int = 1
Pattern matching
Another possibility is to use pattern matching:
scala> def matchAB(eab: Either[A,B]): Int = eab match { case Left(A(i)) => i; case Right(B(i)) => i}
matchAB: (eab: Either[A,B])Int
scala> matchAB(Left(A(1)))
res3: Int = 1
scala> matchAB(Right(B(1)))
res4: Int = 1
Suppose I have the following code:
val someNumbers = List(-11, -10, -5, 0, 5, 10)
someNumbers.foreach( println _ )
val j = 10
(x: Int) => x + j
My question is Are partially applied functions and Closures orthogonal in Scala? This presentation seems to suggest that they are.
EDIT: 13 July 2014 [Changed code above]
It's really easy to see what's being returned when you go into the repl:
scala> type IntPairPred = (Int, Int) => Boolean
defined type alias IntPairPred
scala> val gt: IntPairPred = _ > _
gt: IntPairPred = <function2>
scala> gt(2,3)
res3: Boolean = false
What gt is, is a function2 i.e. a function that takes 2 parameters
Here's another example:
scala> def fn(a: Int, b: Int) = () => a + b
fn: (a: Int, b: Int)() => Int
scala> val a = fn(2,3)
a: () => Int = <function0>
What fn returns, is a function0 i.e. a function that doesn't take any parameters
Sorry but your example doesn't seem to refer to partial application, at least to me.
You're just using some shortcut syntax to define regular functions.
Actually gt, ge, ... definitions are expanded to something pretty like
val gt: IntPairPred = (x: Int, y: Int) => x > y
val gt: IntPairPred = (x: Int, y: Int) => x >= y
//and so on...
Regular functions support modification of its arguments, but this is not what you're looking for, I presume.
To define a closure, you should define a partial function referring to a variable in the outer scope, like
var one = 1
val gt1 = gt(1, _: Int)
assert(gt1(0)) //ok
assert(!gt1(1)) //ok
one = 2 //weirdo!
assert(gt1(0)) //ok
assert(gt1(1)) //ok
assert(!gt1(2)) //ok
So the point is not in functions definition or partial application. The point is if, at definition time, you're using variables from the closing scope within your function. In this case your function is influenced by the variable you closed over.
Is this what you were after?
I have a function that takes a variable number of arguments. The first is a String and the rest are numbers (either Int or Double) so I am using Any* to get the arguments. I would like to treat the numbers uniformly as Doubles, but I cannot just use asInstanceOf[Double] on the numeric arguments. For example:
val arr = Array("varargs list of numbers", 3, 4.2, 5)
val d = arr(1).asInstanceOf[Double]
gives:
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Double
Is there a way to do this? (The function needs to add up all the numbers).
Scala's asInstanceOf is its name for casting. Casting is not converting.
What you want can be accomplished like this:
val mongrel = List("comment", 1, 4.0f, 9.00d)
val nums = mongrel collect { case i: Int => i case f: Float => f case d: Double => d }
val sumOfNums = nums.foldLeft(0.0) ((sum, num) => sum + num)
Here is a slight simplification of Randall's answer:
val mongrel = List("comment", 1, 4.0f, 9.00d)
val nums = mongrel collect { case i: java.lang.Number => i.doubleValue() }
val sumOfNums = nums.sum
Matching for any kind of number turns out to be a little tricky in Scala, see here for another way of doing it.
When there is a need to handle different types, you should avoid casting them and instead use a pattern match. To add up all Double's and Int's of an array you could use:
val array = Array("varargs list of numbers", 3, 4.2, 5)
array.foldLeft(0.0){
case (s, i: Int) => s + i
case (s, d: Double) => s + d
case (s, _) => s
}
The pattern match allows you to treat each different type separately and avoids running into ClassCastExceptions.
Stepping back for a moment, might it be easier to have the function take Double* instead of Any*?
scala> def foo(str: String, nums: Double*) {
nums foreach { n => println(s"num: $n, class: ${n.getClass}") }
}
foo: (str: String, nums: Double*)Unit
scala> foo("", 1, 2.3)
num: 1.0, class: double
num: 2.3, class: double
Is it possible to initialize a class parameter with a function in Scala?
Example:
def square(x: Int) = x*x
class Foo(val x: Int = square(x))
This doesn't compile but I hope you get the idea.
Hard to guess what you're trying to achieve, but let me have a go:
class Foo private (val x: Int)
object Foo {
def apply(x: Int) = new Foo(square(x))
}
Note that if you try this in the REPL, you must enter both the class and its companion object at the same time (in paste mode, via :pa), or the object Foo won't have access to the private class constructor.
This applies the square function to the parameter x before creating a Foo instance:
scala> Foo(3).x
res1: Int = 9
This is not possible because you try to calculate x based on x (without having any kind of base case). You could do the following:
class Foo(_x: Int) {
val x = square(_x)
}
println(new Foo(10).x) // 100
EDIT
You could also generalise this and implicitly pass a function to the class constructor that transforms x:
implicit val square = (x: Int) => x*x
class Foo(private val _x: Int)(implicit f: Int => Int) {
val x = f(_x)
}
println(new Foo(10).x) // 100
This unfortunately doesn't compile as-is (Scala 2.9.2, 2.10.0), because there is another implicit in scope (Predef.conforms). I don't know how to overcome this ambiguity, but it should certainly be possible.
Here it is.. you can initialize a class with a function ! :)
class Foo(f : Int => Int)
def square(x : Int) = x*x
val foo = new Foo(square)
Or Probably you must be looking for this.
class Foo(f : Int => Int, _p1 : Int){
val p1 = f(_p1)
}
def square(x : Int) = x*x //> square: (x: Int)Int
def add2(x : Int) = x+2 //> add2: (x: Int)Int
val fooSqr = new Foo(square,5)
fooSqr.p1 //> res0: Int = 25
val fooAdd2 = new Foo(add2,5)
fooAdd2.p1 //> res1: Int = 7
In general you can use arbitrary expressions when defining the default value (source).
Your problem is that you can not use x on the right hand side of the initialization, because x is probably neither declared nor initialized at that point.
I am new to Scala, and trying to understand the following codes (derived from an example in the Beginning Scala book)
scala> def w42(f: Int => Int) = f(42) //(A)
w42: (f: Int => Int)Int
scala> w42 (1 +) //(B)
res120: Int = 43
I do not understand how "1 +" at point (B) is consider as a function (take 1 Int parameter, and return an Int) that satisfies the w42 definition at point (A)?
Would you mind please explain or point me to some documents that have the answer?
Simple. In Scala 1 + 2 is just a syntax sugar over 1.+(2). This means Int has a method named + that accepts Int:
final class Int extends AnyVal {
def +(x: Int): Int = //...
//...
}
This is why you can use 1 + as if it was a function. Example with less unexpected method naming:
scala> def s42(f: String => String) = f("42")
s42: (f: String => String)String
scala> s42("abc".concat)
res0: String = abc42
BTW Technically speaking, eta-expansion is also involved to convert method to a function.