Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed last year.
Improve this question
I am very new to the Scala programming and while practicing Scala functions I wrote this without any error:
def house (facade:Double, window:Double): Double = {
val Door = 2x1
facade - Door -2 x window
}
house(10,3)
But whenever I try to add another value (subArea) inside the method, it gives the error at 2*window:
Found: Unit
Required: Doublemdoc:
def House (facade:Double, window:Double): Double = val Door = 1x2 val subArea=facade - Door -2 x window}
Please Help.
thanks
If I understand correctly, the code which is giving you a compile error is something like:
def House(facade: Double, window: Double): Double = {
val Door = 1 * 2
val subArea = facade - Door - 2 * window
}
In a method body, the last expression will be the value that is returned. The last line in your method body is an assignment statement. Assignment statements have the type Unit, but the compiler is expecting to return a value of type Double. If you wish to return the value of subArea, make it the last expression in the method body:
def House(facade: Double, window: Double): Double = {
val Door = 1 * 2
val subArea = facade - Door - 2 * window
subArea
}
You could also skip the subArea assignment altogether:
def House(facade: Double, window: Double): Double = {
val Door = 1 * 2
facade - Door - 2 * window
}
Related
I am new in Scala and I am referring book "Scala for Impatient - Second Edition".
I am working on a small code where I have created a class Fraction which as two Int fields num (number) and den(denominator). The class has a method * which performs multiplication of num and den and returns new Fraction instance.
Here, for understanding the working of implicit, I have created an object FractionConversions which helps with two implicit method intToFraction and fractionToDouble.
While testing the code in ImplicitConversionTester, I have imported the FractionConversions._ path, so both of the implicit methods are available to compiler.
Now, refer the code to make the picture more clear.
package OperatorOverloadingAndImplicitConversion
class Fraction(n : Int, d : Int) {
private val num = this.n
private val den = this.d
def *(other : Fraction) = new Fraction(num*other.num, den*other.den)
override def toString: String = {
s"Value of Fraction is : ${(num*0.1)/den}"
}
}
object Fraction {
def apply(n: Int, d: Int): Fraction = new Fraction(n, d)
}
object FractionConversions {
implicit def fractionToDouble(f : Fraction): Double = {
println("##### FractionConversions.fractionToDouble called ...")
(f.num*0.1)/f.den
}
implicit def intToFraction(n : Int) : Fraction = {
println("##### FractionConversions.intToFraction called ...")
new Fraction(n,1)
}
}
object ImplicitConversionTester extends App {
import FractionConversions._
/*
* CASE 1 : Here, "fractionToDouble" implicit is called.
Why "intToFraction" was eligible but not called ?
*/
val a = 2 * Fraction(1,2)
/*
* CASE 2 : Works as expected.
Here, number "2" is converted to Fraction using "intToFraction" implicit.
*/
val b = 2.den
/*
* CASE 3: Why again "intToFraction" but not "fractionToDouble" ? Why ?
*/
val c = Fraction(4,5) * 3
println(a) // output : 0.1 FractionConversions.fractionToDouble called
println(b) // output : 1 FractionConversions.intToFraction called
println(c) // output : Value of Fraction is : 0.24000000000000005. FractionConversions.intToFraction called
}
I have query in above code :
Case#1 : For statement val a = 2 * Fraction(1,2),
Why fractionToDouble implicit is getting called here even though intToFraction is also eligible in this case ?
case#3 : For statement val c = Fraction(4,5) * 3, why intToFraction called ? Why fractionToDouble was not used ?
Here, I tried to replicate the following scenario mentioned in the book, so above question arises.
So, should We summarise that, the compiler avoids converting the left side operand and select the right side to convert if both of them are eligible for conversion ? For example, In case of (a*b), a is always ignored and b is converted to expected type even though a and b both are eligible for conversion ?
Your characterization is correct: for an expression a.f(b) (note that a*b is just operator notation for a.*(b)), an implicit conversion applicable to b which allows the expression to type check will take precedence over an implicit conversion applicable to a. This arises because an implicit conversion (called a "view" in the language standard) of a could only be attempted if * (in Int) was not applicable to Fraction (see SLS 7.3)... however the definition of applicability in SLS 6.6 says that an implicit view is sufficient to be applicable.
Accordingly, if one wanted to implicitly convert 2 to a Fraction to use Fraction.*, one would need
(2: Fraction) * Fraction(1, 2)
Likewise, for case 3, if you want the fraction implicitly converted to a Double first:
(Fraction(4,5): Double) * 3
Im trying to test my code and all I get is a type error. I'm new to scala but as far as I can tell the ide is pointing at a bracket.
I've taken my function out of a main function (not sure what the purpose of that is, new to object oriented programming.) and I've tooled arount with my declarations
class FirstObject {
def computeShippingCosts(weight: Double): Double = {
var init: Double = 5.0
var overW: Double = weight - 30.0
if (weight >= 30) {
var total: Double = init + (overW * .25)
} else {
var total: Double = 5.0
}
}
println(computeShippingCosts(31.0))
}
I would expect the result of the println to be 5.25 but nothing prints other than the error so I don't know what to do.
Firstly, don't use return in Scala, it can cause some very odd errors. The last value in the function will be the result so there is no need for return.
You are getting an error because the last value is val ... and a declaration does not return a value (or rather it has the value Unit, which is the Scala equivalent of void).
It is also a good idea to avoid if/else if there is a function that can do the same thing. In this case you can use max:
def computeShippingCosts(weight: Double): Double =
math.max(5, weight*.25 - 2.5)
I think this also expresses the logic better because it makes it clear that there is a computed cost with a minimum value. And this ensures that a heavier parcel is never cheaper than a lighter parcel, which is harder to guarantee with the original logic.
If you want to retain the original form of code, it looks like this:
def computeShippingCosts(weight: Double): Double = {
val init: Double = 5
val overW: Double = weight - 30.0
if (weight >= 30) {
init + (overW*.25)
} else {
5.0
}
}
Andrey gives an alternative version which is more meaningful if you view the calculation as a base cost with a excess for overweight items:
def computeShippingCosts(weight: Double): Double =
5 + 0.25*(weight - 30).max(0)
This question already has answers here:
How do I write a scala unit test that ensures compliation fails?
(3 answers)
Closed 8 years ago.
I've written some Scala to work with modular arithmetic using path dependent types. The parent class represents a group modulo some integer, and the inner class represents elements of this group.
class ModularInt( modulus : Int ) {
case class Value( value: Int ) {
def plus( a: Value ) : Value = {
val rem: Int = (value + a.toInt) % modulus
if( rem < 0 )
Value(modulus + rem)
else
Value(rem)
}
def toInt = value
}
}
This seems to work correctly (e.g. modulo 7: 6 + 2 = 1).
A nice side effect of using path-dependent types is that numbers modulo different integers will throw a type error if you try to operate them together. However, I would like to insert a test that will confirm this fact.
import org.scalatest.FunSuite
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
#RunWith(classOf[JUnitRunner])
class ModularIntSuite extends FunSuite {
test("a mod n + b mod m => error") {
val n: Int = 3
val m: Int = 4
val modulen = new ModularInt( n )
val modulem = new ModularInt( m )
val a = new modulen.Value(0)
val b = new modulem.Value(0)
assert(a plus b) // catch error here
}
}
However, as a plus b throws a type error at compile time, the test won't even run.
Is there anyway to insert a test for a compile error? Or does the fact that compile errors are tests of correctness themselves mean that this is a redundant check (i.e. what I'm trying to do makes no sense)?
Thanks
The test is redundant. One of the advantages of a strong type system is precisely this, that if you design your types correctly the code won't even compile.
I am learning currying in scala and trying to apply my knowledge on the following piece of code.
object excercise {
def sqrt2(input : Double) : ((Double, Double) => Double, Double) => Double = {
def iter(guessFxn : (Double, Double) => Double, initial : Double) : Double = {
if (isGoodEnough(initial)) initial
else {
val newGuess: Double = guessFxn(initial, input)
iter(guessFxn, newGuess)
}
}
iter
def isGoodEnough(guess: Double): Boolean = {
math.abs(guess * guess - input ) / input < 0.001
}
}
println(sqrt2(2) ( (g: Double, c: Double) => (g + c / g) / 2, 1))
}
What i want to achieve is that sqrt2 should return a function which takes as 2 arguments
1. fxn(that takes 2 doubles as arg and return a double val) 2. double val
When i am trying to run the worksheet it is giving me error
Error: missing arguments for method iter;
follow this method with `_' if you want to treat it as a partially applied function
iter
^
Error: type mismatch;
found : Unit
required: ((Double, Double) => Double, Double) => Double
}
^
Error: missing arguments for method iter;
follow this method with `_' if you want to treat it as a partially applied function
iter
^
You just have to inverse the order of those piece of codes:
iter
def isGoodEnough(guess: Double): Boolean = {
math.abs(guess * guess - input ) / input < 0.001
}
becomes:
def isGoodEnough(guess: Double): Boolean = {
math.abs(guess * guess - input ) / input < 0.001
}
iter
Indeed, ending with an inner declared method involves a return type of Unit...that's not what you want.
Besides, you had this advice:
follow this method with `_' if you want to treat it as a partially applied function
iter
because as explains before, iter method is not returned (since its call is not made at the end of the method) and thus compiler expects it to be executed.
Of course, to be executed, it needs its compulsory parameters, that you didn't provide.
So the compiler "thinks" that you expected to partially apply the function but badly. Note than a partially applied function is not the same concept than a partial function, that has a different meaning ... ).
It would allow to defer the call, and it's mostly used when dealing standard function (not curried), where we might need to provide only the first parameter and later the following.
Example of partially applied function:
def sum(i: Int, j: Int){...}
calls:
sum 1 _ //just the second parameter needs to be applied later.
sum _ //none parameter is specified, would need to specify both later.
sum 1 2 //complete call, not partially applied so
You can find a good use case of partially applied function here.
I got the following code snippet referring an example in Chapter 6 of "Programming Scala":
object HelloWorld {
def main(args: Array[String]) {
trait AbstractT2 {
println("In AbstractT2:")
val value: Int
val inverse = 1.0 / value // ???
println("AbstractT2: value = " + value + ", inverse = " + inverse)
}
val c2b = new AbstractT2 {
println("In c2b:") //---->line 1
val value = 10 //---->line 2
}
println("c2b.value = " + c2b.value + ", inverse = " + c2b.inverse)
}
}
The result of the above code is:
In AbstractT2:
AbstractT2: value = 0, inverse = Infinity
In c2b:
c2b.value = 10, inverse = Infinity
Since the anonymous class initialization is after the trait initialization, the result is understandable. But if I exchange line 1 and line 2 in the above example, so that val value = 10 precedes println("In c2b:"), the result will be:
In AbstractT2:
AbstractT2: value = 10, inverse = 0.1
In c2b:
c2b.value = 10, inverse = 0.1
It seems this time the initialization is successful although it's wrong from language point of view. I can't understand why. Can anybody help on this? Thanks a lot.
Initialization semantics changed from 2.7 to 2.8. Here's the commit, way back in 2008. "HARD HATS ON!"
https://lampsvn.epfl.ch/trac/scala/changeset/16745
Up to 2.7 Scala moved value initializations in front of the superclass constructor
until an initialization which references this was encountered. There it would stop.
Much, much earlier, this behavior was necessary to get some composition patterns working. Later, we introduced early definitions to get the same patterns working in a more robust way.
But since the behavior was difficult to change it took us until 2.8 to actually do it.