How to create custom operators with precedence - scala

I hava a class with custom Operators
case class Num(var value:Int) {
def add(x:Num) = Num(value + x.value)
def mul(x:Num) = Num(value * x.value)
}
So I can call them like this
val a = Num(2)
val b = Num(3)
val c = Num(4)
val m1 = a add b mul c
But how can I execute mul before add? I saw a solution like +| instead of add, but I want include letters in my Operator and +add and *mul not working. Also I want to include a pow function, so this needs an higher precidence than mul

You can use Parenthesis after add.
val m1 = a add (b mul c) = 14
val m1 = a add b mul c = 20
Update
you do not have any restrictions in naming your methods. For example, you can define methods +, -, * and etc. for a class.
case class Num(var value:Int) {
def + (x:Num) = Num(value + x.value)
def *(x:Num) = Num(value * x.value)
}
object Num extends App {
val a = Num(2)
val b = Num(3)
val c = Num(4)
val m1 = a + b * c
println(m1)
}
Output
Num(14)

Related

How to append an element to an Iterator in scala

I want to append an element to the end of an iterator like this:
val a = Iterator(3, 4)
val b = a + 5 // expect b == Iterator(3,4,5), but there is no + method
val b2 = a ++ Iterator(5) // That works, but not concise.
Is there a better way than b2 to make this?
You can always just hide the not-concise syntax behind something that you like better.
implicit class IterPlus[A](itr: Iterator[A]) {
def +(elem: A) = itr ++ Iterator(elem)
}
val a = Iterator(3, 4)
val b = a + 5 //Iterator(3, 4, 5)

Scala case class, conditional Copy

I've defined a case class and a value:
scala> case class N(a:Int, b:Int)
defined class N
scala> val nnn = N(2,3)
nnn: N = N(2,3)
I would like to modify a field based on an optional value, t1 and t2 with type Option[Int], this is what i did:
val nnn1 = t1.map( x => nnn.copy( a = x)).getOrElse(nnn)
val nnn2 = t2.map( x => nnn1.copy( b = x)).getOrElse(nnn1)
Theres a Lens/Monocle/Scalaz way to do it generic?
A good approach colud be
def someF(i:Int) = // a great computation with i :)
val na = t1.map(someF).getOrElse(nnn.a)
val newnnn = nnn.copy(a = na, b = t2.getOrElse(nnn.b))
In a case where you have to apply someF to t1 is probably a good idea separate it.
No lens for you.

Generate alphanumeric string

I need some test company-names, like "rnd_company_blah23haf9", "rnd_company_g356fhg57" etc.
Is it possible to do something like
import scala.util.Random
val company = s"rnd_company_${Random.alphanumeric take 10 ?????}"
provided someone can fill out ????? of course.
Use .mkString("") to create a String from the Stream :
scala> val company = s"rnd_company_${Random.alphanumeric take 10 mkString}"
company: String = rnd_company_BbesF0EY1o
You have an example here
scala> val x = Random.alphanumeric
x: scala.collection.immutable.Stream[Char] = Stream(Q, ?)
scala> x take 10 foreach println
Q
n
m
x
S
Q
R
e
P
B
So you can try this:
import scala.util.Random
val company = s"rnd_company_${(xx take 10).mkString}"
Something verbose than the above answers but this one helps you to constrain the alphabet:
def randomText(textLength: Int = 10, alphabet: List[Char] = ('a' to 'd').toList) = {
(1 to textLength).toList.map { charPos =>
val randomIndex = (Math.random() * alphabet.length).floor.toInt
alphabet(randomIndex)
}.mkString("")
}

'let...in' expression in Scala

In OCaml, the let...in expression allows you to created a named local variable in an expression rather than a statement. (Yes I know that everything is technically an expression, but Unit return values are fairly useless.) Here's a quick example in OCaml:
let square_the_sum a b = (* function definition *)
let sum = a + b in (* declare a named local called sum *)
sum * sum (* return the value of this expression *)
Here's what I would want the equivalent Scala to look like:
def squareTheSum(a: Int, b: Int): Int =
let sum: Int = a + b in
sum * sum
Is there anything in Scala that I can use to achieve this?
EDIT:
You learn something new every day, and this has been answered before.
object ForwardPipeContainer {
implicit class ForwardPipe[A](val value: A) extends AnyVal {
def |>[B](f: A => B): B = f(value)
}
}
import ForwardPipeContainer._
def squareTheSum(a: Int, b: Int): Int = { a + b } |> { sum => sum * sum }
But I'd say that is not nearly as easy to read, and is not as flexible (it gets awkward with nested lets).
You can nest val and def in a def. There's no special syntax; you don't need a let.
def squareTheSum(a: Int, b: Int): Int = {
val sum = a + b
sum * sum
}
I don't see the readability being any different here at all. But if you want to only create the variable within the expression, you can still do that with curly braces like this:
val a = 2 //> a : Int = 2
val b = 3 //> b : Int = 3
val squareSum = { val sum = a + b; sum * sum } //> squareSum : Int = 25
There is no significant difference here between a semicolon and the word "in" (or you could move the expression to the next line, and pretend that "in" is implied if it makes it more OCaml-like :D).
val squareSum = {
val sum = a + b // in
sum * sum
}
Another, more technical, take on this: Clojure's 'let' equivalent in Scala. I think the resulting structures are pretty obtuse compared to the multi-statement form.

"Whole function VS just the function statements" inside the brace

What is the diference between func1 and func2 body. Both compiles but I couldn't figure out how scala can recognize multiple statements in func2 as brace is putted before a => but the statements are after that.
val func1: Int => Int = a => {
val b = a * 2
b + 2
}
val func2: Int => Int = { a =>
val b = a * 2
b + 2
}
Even this one compiles
val func3: Int => Int = { a => val b = a * 2; b + 2 }
But this one doesn't
val func4: Int => Int = a => val b = a * 2; b + 2
It's because when you don't use {} you can only have one expression and val b = a * 2; b + 2 are two expressions. The parser considers it something like:
val func4: Int => Int = a => val b = a * 2;
b + 2
Which doesn't compile because there isn't a b in scope and the type of the expression val b = a * 2; is Unit, which doesn't satisfies func4s type.
Other than that, func 1 through 3 are equivalent.