implicit val odkaz = head;
def vypis(implicit odkaz:Prvek):String = {
odkaz match{
case null => ""
case e => e.cislo + " " + e.pocet + "\n" + vypis(e.dalsi)
}
}
...
def main(args:Array[String]){
val q = new MyQueue() // insert some values
println(q.vypis)
}
This method(vypis) is a member of an queue-class so I'll always want to implicity start the recursion from the start of the queue, when calling the method from outside. Is there a way how to write it, that the method from outside calling, there's no paramter, but in inside, there's a parameter - for recursion...?
The compiler complains that the parameter is not defined when called from outside
Or is there are way how can specify the default value for a method's parameter?
Using a nested method
def sum(list: List[Int]) = {
#annotation.tailrec
def sum(ls: List[Int], s: Int): Int = ls match {
case x :: xs => sum(xs, x + s)
case _ => s
}
sum(list, 0)
}
Using a default parameter for the accumulator
#annotation.tailrec
def sum(list: List[Int], s: Int = 0): Int = list match {
case x :: xs => sum(xs, x + s)
case _ => s
}
The second approach (only possible with Scala 2.8) unneccesarily broadens the public API, so I would recommend the first.
In Scala 2.8, default method (and constructor) parameters are available:
def m1(i: Int = 23): Int = i * 2
Related
I get "type mismatch; found : Int(1) required: String" error when I try to return the incremented value of the input parameter from a Scala generic method below.
I did try using the Case method for this but it did not work as well. Basically I want to decide the operation based on input Type to the method and return the calculated/modified value.
object GenericOperations {
// def increment[typ](val x:typ):typ = x match {
// case _:Int => x + 1
// case _:String => x + "x"
// }
def increment2(x:Any):Any = {
if(x.isInstanceOf[Int]) {
x+1
}
else if (x.isInstanceOf[String]) {
x + "x"
}
else {
println("No Match type")
}
}
}
I would rather use method overloading:
def increment2(x: Int) = x + 1
def increment2(x: String) = x + "x"
If you are sure you need exactly one function you may use match.
def increment2(x: Any): Any = x match {
case v: Int => v + 1
case v: String => v + "x"
case _ =>
throw new Exception("No Match type")
}
But returning Any isn't good thing as you cannot use its result without type cast
GenericOperations.increment2(3) + 3 // type mismatch
Still you may use the same match way:
def increment2[T](x: T): T = (x match {
case v: Int => v + 1
case v: String => v + "x"
case _ => throw new Exception("No Match type")
}) match {
case v: T => v
case _ => throw new Exception("Invalid increment expression result type")
}
As it has been mentioned in the comments there is also typeclass way:
//type class
trait Incrementable[T] {
def inc(x: T): T
}
//type class instance for String
implicit val incString = new Incrementable[String] {
def inc(x: String) = x + "x"
}
//type class instance for Int, single abstract method (SAM) form
implicit val incInt: Incrementable[Int] = (x: Int) => x + 1
def increment2[T: Incrementable](x: T): T = implicitly[Incrementable[T]].inc(x)
You have declared x to be of type Any. Which means you are only allowed to use the methods of Any.
You are calling x.+(1). There is no + method in Any. Therefore, you can't use +.
You should be getting an error about + not existing, but you don't, so what's happening here?
There is an implicit conversion for string concatenation, which can convert an arbitrary object into a String and then concatenate another String to it. In this case, it converts x to an any2stringadd and then tries to add 1 to it, but the any2stringadd.+ method only takes a String as its argument, and thus you get the strange error message that it is expecting a String.
You, however, are passing 1 as an argument, which is an Int not a String.
Note that any2stringadd is deprecated in Scala 2.13, so in the future you would just get an error about a non-existent method.
Note that you have tagged this question with generics and also talk about generics multiple times in the subject and the question body, yet there are no generics in your code. In fact, with generics, this problem would not exist.
See also
Scala Beginner trying to use Parameterised Type
Type parameter in scala
Maybe something like this , even though I still don't like it because the usage of getOrElse , but here you go anyway:
object GenericOperations {
// def increment[typ](val x:typ):typ = x match {
// case _:Int => x + 1
// case _:String => x + "x"
// }
def increment2(x:Any):Any = {
if(x.isInstanceOf[Int]) {
toInt(x).getOrElse(0)+1
}
else if (x.isInstanceOf[String]) {
x + "x"
}
else {
println("No Match type")
}
}
def toInt(x: Any): Option[Int] = x match {
case i: Int => Some(i)
case _ => None
}
}
Question
Is there a way to define the insert function inside the makeOrderedLeafList match block?
Problem
Since insert function is only used in makeOrderedLeafList, I would like to define it inside it. However, if placed at the bottom, an error "Unit required". Cannot place at the top as "case" is being expected.
def makeOrderedLeafList(freqs: List[(Char, Int)]): List[Leaf] = freqs match {
case List() => List()
case h :: t => insert(h, makeOrderedLeafList(t))
case _ => throw new IllegalStateException
}
//--------------------------------------------------------------------------------
// Insert Leaf in the sorted list of Leaf.
//--------------------------------------------------------------------------------
def insert(c: (Char, Int), list: List[Leaf]): List[Leaf] = list match {
case List() => List(new Leaf(c._1, c._2))
case h :: t => {
//--------------------------------------------------------------------------------
// If C:[char, counter] is smaller, prepend it to the List[Leaf].
// Otherwise, recurse call insert to find a position in the tail of the list.
//--------------------------------------------------------------------------------
if (c._2 <= h.weight) new Leaf(c._1, c._2) :: list
else h :: insert(c, t)
}
}
Just place it inside the case before calling it:
scala> "hello" match {
| case "hel" => 1
| case "hello" =>
| def f(i: Int): Int = {
| i * 2
| }
| f(3) // don't forget to call the function...
| }
res0: Int = 6
The right-hand side of a case expression can be any code block that returns the expected type. A code block can contain function definitions.
If you define you function inside the outer function call, it will create a new instance of inner function on every call of outer function.
val getInnerFuncHash = () => {
val func = (x: Int) => x + 1
func.hashCode().toString
}
println(getInnerFuncHash())
println(getInnerFuncHash())
println(getInnerFuncHash())
this will print the hashCodes for the inner functions, and will output something like,
1136974570
1030088901
2115208183
which means every call to outer function will create a new instanc eof inner function.
The same thing happens in case of defs
def getInnerFuncHash(): String = {
val func = (x: Int) => x + 1
func.hashCode().toString()
}
println(getInnerFuncHash())
println(getInnerFuncHash())
println(getInnerFuncHash())
def max(xs: List[Int]): Int = {
if (xs.isEmpty) throw new java.util.NoSuchElementException("List is Empty")
else
max1(0,xs)
def max1(num :Int, x : List[Int]) : Int = {
if(x.isEmpty) return num
else if(num>x.head) max1(num,x.tail)
else
max1(x.head,x.tail)
}
}
I am trying to Implement code to throw error when it gets an empty list as input and trying to get the maximum value of the list in a recursive way using another helper function
error: type mismatch; found : Unit required: Int
Put the definition of max1 before the if statement.
The return value of a function is the result of the last statement in its body. The way you have it now, the last statement is def, and it's result is Unit.
You can use user require()
For example with this more idiomatic recursion code:
def max(xs: List[Int]): Int = {
require( xs.nonEmpty, ">>> Empty List <<<" )
def max1( num:Int, x:List[Int] ) : Int = x match {
case Nil => num
case y :: ys => max1( (if( num>y ) num else y), ys )
}
max1(0,xs)
}
Then,
max(List())
returns: java.lang.IllegalArgumentException: requirement failed: >>> Empty List <<<
You can use these code to solve that problem.
object Maximum {
def apply(numbers: List[Int]): Int = {
if (numbers.isEmpty) throw new Exception("List shouldn't be empty")
max(numbers)
}
private def max(numbers: List[Int], maxNumb: Int = 0): Int = numbers match {
case x::xs => if (x > maxNumb) max(xs, x) else max(xs, maxNumb)
case Nil => maxNumb
}
}
Maximum(List(1,9,9,12,34))
Maximum(List())
Define
trait XInt
case class N(i: Int) extends XInt
case object NoInt extends XInt
and on pattern-matching an empty list return NoInt and otherwise an N instance.
I learned about extractors from the stairway book:
object Twice {
def apply(x: Int) = x * 2
def unapply(x: Int) = if(x % 2 == 0) Some(x / 2) else None
}
// outside pattern mathcing, Twice.apply(21) is called
val x = Twice(21)
x match {
// inside pattern matching, Twice.unapply(x) is called,
// the result Some(21) is matched against y,
// y gets the value 21
case Twice(y) => println(x + " is twice " + y)
case _ => println(x + " is odd.")
}
That's pretty straight forward. But today I read from some book on Play framework this code:
trait RequestExtractors extends AcceptExtractors {
//Convenient extractor allowing to apply two extractors.
object & {
def unapply(request: RequestHeader): Option[(RequestHeader, RequestHeader)] = Some((request, request))
}
}
//Define a set of extractors allowing to pattern match on the Accept HTTP header of a request
trait AcceptExtractors {
//Common extractors to check if a request accepts JSON, Html, etc.
object Accepts {
import play.api.http.MimeTypes
val Json = Accepting(MimeTypes.JSON)
val Html = Accepting(MimeTypes.HTML)
val Xml = Accepting(MimeTypes.XML)
val JavaScript = Accepting(MimeTypes.JAVASCRIPT)
}
}
//Convenient class to generate extractors checking if a given mime type matches the Accept header of a request.
case class Accepting(val mimeType: String) {
def unapply(request: RequestHeader): Boolean = request.accepts(mimeType)
def unapply(mediaRange: play.api.http.MediaRange): Boolean = mediaRange.accepts(mimeType)
}
def fooBar = Action {
implicit request =>
val xmlResponse: Node = <metadata>
<company>TinySensors</company>
<batch>md2907</batch>
</metadata>
val jsonResponse = Json.obj("metadata" -> Json.arr(
Json.obj("company" -> "TinySensors"),
Json.obj("batch" -> "md2907"))
)
render {
case Accepts.Xml() => Ok(xmlResponse)
case Accepts.Json() & Accepts.JavaScript() => Ok(jsonResponse)
}
}
How does the extractor work when the unapply function returns Boolean instead of Option? How do &, Accepts.Xml work here?
I can really tell you about the play framework, but if used in pattern matching an extractor returning a boolean signifies if the pattern matches. Thus if an extractor return true it means that the pattern matches the value. This is a good link about extractors and also covers this case:
http://danielwestheide.com/blog/2012/11/21/the-neophytes-guide-to-scala-part-1-extractors.html
Generally you use extractors for two use cases:
1) Destructing an object, which means returning one or more values which represent the state of given object
2) You can also use extractors to turn an object into an object of another kind during pattern matching. I made a small example for this case:
class Division(val number: Int) {
}
object Division {
def unapply(divider: Division): Boolean = divider.number != 0
def unapply(divider: Int): Option[Division] = if (divider != 0) Some(new Division(divider)) else None
}
val divident = 15
val divider = 5
val y = divider match {
case Division(notZero) => divident / notZero.number //notZero is of type Division
case _ => throw new IllegalArgumentException()
}
Ok, I found a way to figure this out by making a minimal example:
object Unapply {
case class DividedBy(val number: Int) {
def unapply(divider: Int): Boolean = number % divider == 0
def unapply(divider: Double): Boolean = number % divider.toInt == 0
}
val x = DividedBy(15)
// y should be true
val y = 5 match {
// case DividedBy(15)() => true
case x() => true
case _ => false
}
}
The weird thing is that when you use DividedBy(15)() (commented out above), the code won't compile.
Update:
object Unapply {
case class Division(val number: Int) {
// def unapply(divider: Int): Boolean = number % divider == 0
def unapply(divider: Int): Option[(Int, Int)] = if (number % divider == 0) Some(number/divider, 0) else None
def unapply(divider: Double): Boolean = number % divider.toInt == 0
}
object Division {
def apply(number: Int) = new Division(number)
}
val divisionOf15 = Division(15)
// y should be true
val y = 5 match {
// case DividedBy(15)() => true
case divisionOf15(z, w) => s"$z, $w"
case _ => s"Not divisible"
}
val z = 5.0 match {
case divisionOf15() => "Divisible"
case _ => "Not divisible"
}
}
After some reading some old notes on the stairway book now I have a clearer understanding of this. The case class is a extractor factory.
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 })