Runtime exception in syntax like defining two vals with identical names - scala

In some book I've got a code similar to this:
object ValVarsSamples extends App {
val pattern = "([ 0-9] +) ([ A-Za-z] +)". r // RegEx
val pattern( count, fruit) = "100 Bananas"
}
This is supposed to be a trick, it should like defining same names for two vals, but it is not.
So, this fails with an exception.
The question: what this might be about? (what's that supposed to be?) and why it does not work?
--
As I understand first: val pattern - refers to RegEx constructor function.. And in second val we are trying to pass the params using such a syntax? just putting a string

This is an extractor:
val pattern( count, fruit) = "100 Bananas"
This code is equivalent
val res = pattern.unapplySeq("100 Bananas")
count = res.get(0)
fruit = res.get(1)

The problem is your regex doesn't match, you should change it to:
val pattern = "([ 0-9]+) ([ A-Za-z]+)". r
The space before + in [ A-Za-z] + means you are matching a single character in the class [ A-Za-z] and then at least one space character. You have the same issue with [ 0-9] +.
Scala regexes define an extractor, which returns a sequence of matching groups in the regular expression. Your regex defines two groups so if the match succeeds the sequence will contain two elements.

Related

Assigning value to arg with val object(arg) = object

I am following this tutorial on GraphQL with Sangria. I am wondering about the following line
val JsObject(fields) = requestJSON
where requestJSON is an object of JsValue. This way of assigning fields is new to me and my question is, if you could name that pattern or provide me with a link to a tutorial regarding this structure.
The important thing to know is that val definitions support a Pattern on the left-hand side of the assignment, thus providing (subset of the functionality of) Pattern Matching.
So, your example is equivalent to:
val fields = requestJSON match {
case JsObject(foo) => foo
}
See Scala Language Specification Section 4.1 Value Declarations and Definitions for details.
So, for example, if you have a list l and you want to assign the first element and the rest, you could write:
val x :: xs = l
Or, for the fairly common case where a method returns a tuple, you could write:
val (result1, result2) = foo()
It is the Extractor pattern, you can reach the same result implementing the unapply method on your arbitrary object (like shown in the example). When you create a case class the compiler produces an unapply method for you, so you can do:
case class Person(name : String, surname : String)
val person = Person("gianluca", "aguzzi")
val Person(name, surname) = person

Scala - Can Match-extraction be used on backtick identifiers?

The question is a little difficult to phrase so I'll try to provide an example instead:
def myThing(): (String, String, String) = ("", "", "")
// Illegal, this is a Match
val (`r-1`, `r-2`, `r-3`) = myThing()
// Legal
val `r-1` = myThing()._1
The first evaluation is invalid because this is technically a match expression, and in a match backtick marked identifiers are assumed to be references to an existing val in scope.
Outside of a match though, I could freely define "r-1".
Is there a way to perform match extraction using complex variable names?
You can write out the full variable names explicitly:
def myThing(): (String, String, String) = ("a", "b", "c")
// legal, syntactic backtick-sugar replaced by explicit variable names
val (r$minus1, r$minus2, r$minus3) = myThing()
println(`r-1`, `r-2`, `r-3`)
But since variable names can be chosen freely (unlike method in Java APIs that are called yield etc.), I would suggest to invent simpler variable names, the r$minusx-things really don't look pretty.

list of string matching with input string

I am learning scala and I have the following issue:
Given a list in input
val listin = List("Apple,January,10",
"Banana,August,15",
"Strawberry,June,20")
and a String val inputstring="Banana,August"
I want to find the price in column matching with the string.
I wrote the following code :
case class Fruit(name:String, month:String,price:Int)
val splitString=inputstring.split(",")
val listSplit=listin.map(_.spilt(","))
But I don't know how to match the case of equality between the string and a line in the list
The expected result is
val output="Banana_August_15"`
Not sure why you want to replace the commas with underscores, or what purpose the case class serves, but this produces the requested result.
listin.filter(_.startsWith(inputstring+","))
.map(_.replaceAllLiterally(",","_")
//res0: List[String] = List(Banana_August_15)

Find longest prefix that matches a certain condition in scala

I am trying to figure out a way to find out longest prefix of a string which matches a certain condition.
It is trivial to write a imperative method which does exactly that, but I am new to scala and wondering if there is an idiomatic scala (or functional) way to do that.
Keep iterating through longest prefixes (mystring.take(mystring.size),..mystring.take(1)
Apply a predicate on each of those substrings
If a prefix matches a predicate, break the loop and return the longest prefix.
For example, this:
def predicate(str: String): Boolean = ???
val longest_matching: Option[String] =
Iterator(mystring.size, 0, -1) // iterator of lengths
.map(mystring.take) // take string prefix
.find(predicate) // find first matching entry
longest_matching.fold {
println("No matching prefix")
} { prefix =>
println("Longest matching prefix: " + prefix)
}
You can take full advantage of the Scala standard library by using inits:
val longest_matching = mystring.inits.find(predicate)

What does this Scala syntax mean - a value definition followed by open brace and indented stuff?

I'm trying to decipher somebody else's code. The following appeared in a Scala trait. This isn't its exact content, I flattened out some of the detail to make it more general (it had some extra lines before the closed-curly-bracket incorporating a zipWithIndex method, and some other pattern matching stuff.) My main concern was that I am not familiar with this concept; a value definition that begins with an open-curly-bracket and then a bunch of indented stuff.
val example: ExampleType = {
val anOtherExample = "String"
val yetAnOtherExample = 22
new ExampleType(anOtherExample, yetAnOtherExample)
}
Having experience with C-like languages and/or Java, you may be used to the fact that curly braces {} denote a block of code - i.e. just a set of instructions that will be invoked.
Scala is different on this part, because in Scala almost everything is an expression, i.e. almost everything evaluates to some value and therefore can be assigned to a val, passed as an argument, etc.
Therefore, a block of code in Scala is not just a sequence of instructions, but a valid expression that can be assigned and passed around. Block of code evaluates to the last expression in that block, i.e.
val x: Int = {
doSomething()
doSomethingElse()
42
}
In the above example, x will have 42 assigned as its value.
{
val anotherExample = "String"
val yetAnotherExample = 22
}
This is called block. It is evaluated to its last statement. Here the last statement is an assignment val yetAnotherExample = 22 which is of type Unit in Scala. So your code will not compile if your ExampleType is not the same type as Unit.