Scala "Sentence-Like" Function Definition [duplicate] - function

This question already has answers here:
When to use parenthesis in Scala infix notation
(4 answers)
Closed 7 years ago.
I am refactoring some code and wanted to learn how Scala methods are written so that they can be written like:
foo = Map("Hello" -> 1)
foo contains "Hello"
where "contains" is the style I am looking to emulate. Here is the code I am refactoring (from exercism.io):
class Bob {
def hey(statement:String): String = statement match {
case x if isSilent(x) => "Fine. Be that way!"
case x if shouting(x) => "Whoa, chill out!"
case x if asking(x) => "Sure."
case _ => "Whatever."
}
def isSilent2:String => Boolean = _.trim.isEmpty
def isSilent (str:String) = str.trim.isEmpty
def shouting(str:String): Boolean = str.toUpperCase == str && str.toLowerCase != str
def asking(str:String): Boolean = str.endsWith("?")
}
Ideally, I'd like to make my isSilent, shouting, and asking functions all able to be written in that style so that I can write:
case x if isSilent x => ...
Thanks for your help! Additionally, knowing what this is called in Scala (and other functional languages, because I think Haskell has something similar) would be really helpful as I've done quite a bit of searching and couldn't find what I was trying to describe.

This is referred to as Infix Notation and it doesn't require anything special so long as you have a single argument function.
The reason it isn't working for you is that you need the object whose method is being called. The following compiles:
class Bob {
def hey(statement:String): String = statement match {
case x if this isSilent x => "Fine. Be that way!"
case x if this shouting x => "Whoa, chill out!"
case x if this asking x => "Sure."
case _ => "Whatever."
}
def isSilent2:String => Boolean = _.trim.isEmpty
def isSilent (str:String) = str.trim.isEmpty
def shouting(str:String): Boolean = str.toUpperCase == str && str.toLowerCase != str
def asking(str:String): Boolean = str.endsWith("?")
}

Related

Is def x = 1 in Scala a variable declaration or a function? [duplicate]

This question already has answers here:
What is the difference between def foo = {} and def foo() = {} in Scala?
(4 answers)
Closed 7 years ago.
Is def x = 1 a function or a variable declaration? And, what is the difference between:
def x = 1 // REPL x: Int
def x() = 1 // REPL x: () Int
Looks like the first one is a variable definition. Please clarify.
No difference at all. Braces are optional for methods with no arguments in Scala. It is a convention to use them, if the method modifies any kind of state, and to leave the away, if it does not (at the call site too).
Both are method definitions. var x = 1 or val x = 1 would be variable definitions.

Scala DSL and Block as function argument

How can i implement that DSL construction at Scala
def objeects(f: => Int):Int {
println(f)
// ??? evaluate every function, that f contain in the block.
}
manytimes {
1+1
2+1
3+1
}
At result we need get one computation for every functions as we pass in block to that method.
9
Your block is one function:
{
1+1 // calculate 2 and throw away
2+1 // calculate 3 and throw away
3+1 // return 4
}
This is simply how Scala syntax works, and you can't change it. Indeed, if you could, what would you expect to happen in this case?
manytimes {
val x = 1
val y = 2
x + y
}
Will
manytimes(1+1)(2+1)(3+1)
be good enough for your purposes?
After many hours of searching i found some really great components, that can help me solve my problem.
multifunc {
println(1)
println(2)
}
// output
Expr[c.universe.Tree](func.tree)
scala.this.Predef.println(2) // <-- it my case its the second and last elem
class scala.reflect.internal.Trees$Apply // <-- we can apply it as usual
class scala.reflect.internal.Trees$Block
tree<<
class scala.reflect.internal.Trees$EmptyTree$
<empty>
Macro for that:
import scala.language.experimental.macros
import scala.reflect.macros._
def multifunc[A](func: => A) = macro _multifunc[A]
def _multifunc [A](c: BlackboxContext)(
func: c.Expr[A]
): c.Expr[Unit] = {
import c.universe._
val tree = func.tree match {
case q"($i: $t) => $body" => q"""
println($body)
println($body.getClass)
$body
"""
case _ => q""
}
println(func.tree.children.last) // <-- accessor to AST children
println(func.tree.children.last.getClass)
println(func.tree.getClass)
println("tree<<")
println(tree.getClass)
println(tree)
c.Expr(tree)
}

How do I make lambda functions generic in Scala? [duplicate]

This question already has answers here:
How can I define an anonymous generic Scala function?
(2 answers)
Closed 9 years ago.
As most of you probably know you can define functions in 2 ways in scala, there's the 'def' method and the lambda method...
making the 'def' kind generic is fairly straight forward
def someFunc[T](a: T) { // insert body here
what I'm having trouble with here is how to make the following generic:
val someFunc = (a: Int) => // insert body here
of course right now a is an integer, but what would I need to do to make it generic?
val someFunc[T] = (a: T) => doesn't work, neither does val someFunc = [T](a: T) =>
Is it even possible to make them generic, or should I just stick to the 'def' variant?
As Randall Schulz said, def does not create a function, but a method. However, it can return a function and this way you can create generic functions like the identity function in Predef. This would look like this:
def myId[A] = (a: A) => a
List(1,2,3) map myId
// List(1,2,3)
List("foo") map myId
// List("foo")
But be aware, that calling myId without any type information infers Nothing. In the above case it works, because the type inference uses the signature of map, which is map[B](f: A => B) , where A is the type of the list and B gets infered to the same as A, because that is the signature of myId.
I don't believe it's possible. You can look at this previous post for more details:
How can I define an anonymous generic Scala function?
The only way around it (as one of the answers mentions) is to extend something like FunctionX and use a generic at the class level and then use that in the override of the apply function.
I don't believe it's possible either, but I'm a pessimist.
http://www.chuusai.com/2012/04/27/shapeless-polymorphic-function-values-1/
Edit:
Tell me if this isn't what you're asking, but this is why the accepted answer isn't what I thought you were asking for, see the link:
scala> :pa
// Entering paste mode (ctrl-D to finish)
def myId[A] = (a: A) => a
List(1,2,3) map myId
// List(1,2,3)
List("foo") map myId
// List("foo")
// Exiting paste mode, now interpreting.
myId: [A]=> A => A
res0: List[String] = List(foo)
scala> val f1 = myId[Int]
f1: Int => Int = <function1>
scala> val f2 = myId[String]
f2: String => String = <function1>
scala> List(1,2,3) map f2
<console>:10: error: type mismatch;
found : String => String
required: Int => ?
List(1,2,3) map f2
^
scala> List("foo") map f1
<console>:10: error: type mismatch;
found : Int => Int
required: String => ?
List("foo") map f1
^
The function values are not polymorphic, i.e., generic.
The closest thing is polymorphic functions I believe:
https://github.com/milessabin/shapeless#polymorphic-function-values

Why is my Scala function returning type Unit and not whatever is the last line?

I am trying to figure out the issue, and tried different styles that I have read on Scala, but none of them work. My code is:
....
val str = "(and x y)";
def stringParse ( exp: String, pos: Int, expreshHolder: ArrayBuffer[String], follow: Int )
var b = pos; //position of where in the expression String I am currently in
val temp = expreshHolder; //holder of expressions without parens
var arrayCounter = follow; //just counts to make sure an empty spot in the array is there to put in the strings
if(exp(b) == '(') {
b = b + 1;
while(exp(b) == ' '){b = b + 1} //point of this is to just skip any spaces between paren and start of expression type
if(exp(b) == 'a') {
temp(arrayCounter) = exp(b).toString;
b = b+1;
temp(arrayCounter)+exp(b).toString; b = b+1;
temp(arrayCounter) + exp(b).toString; arrayCounter+=1}
temp;
}
}
val hold: ArrayBuffer[String] = stringParse(str, 0, new ArrayBuffer[String], 0);
for(test <- hold) println(test);
My error is:
Driver.scala:35: error: type mismatch;
found : Unit
required: scala.collection.mutable.ArrayBuffer[String]
ho = stringParse(str, 0, ho, 0);
^one error found
When I add an equals sign after the arguments in the method declaration, like so:
def stringParse ( exp: String, pos: Int, expreshHolder: ArrayBuffer[String], follow: Int ) ={....}
It changes it to "Any". I am confused on how this works. Any ideas? Much appreciated.
Here's a more general answer on how one may approach such problems:
It happens sometimes that you write a function and in your head assume it returns type X, but somewhere down the road the compiler disagrees. This almost always happens when the function has just been written, so while the compiler doesn't give you the actual source (it points to the line where your function is called instead) you normally know that your function's return type is the problem.
If you do not see the type problem straight away, there is the simple trick to explicitly type your function. For example, if you thought your function should have returned Int, but somehow the compiler says it found a Unit, it helps to add : Int to your function. This way, you help the compiler to help you, as it will spot the exact place, where a path in your function returns a non-Int value, which is the actual problem you were looking for in the first place.
You have to add the equals sign if you want to return a value. Now, the reason that your function's return value is Any is that you have 2 control paths, each returning a value of a different type - 1 is when the if's condition is met (and the return value will be temp) and the other is when if's condition isn't (and the return value will be b=b+1, or b after it's incremented).
class Test(condition: Boolean) {
def mixed = condition match {
case true => "Hi"
case false => 100
}
def same = condition match {
case true => List(1,2,3)
case false => List(4,5,6)
}
case class Foo(x: Int)
case class Bar(x: Int)
def parent = condition match {
case true => Foo(1)
case false => Bar(1)
}
}
val test = new Test(true)
test.mixed // type: Any
test.same // type List[Int]
test.parent // type is Product, the case class super type
The compiler will do its best to apply the most specific type it can based on the possible set of result types returned from the conditional (match, if/else, fold, etc.).

Passing a function to an argument in Scala

Is there any way to do something like argument.<keyword>(function) in Scala?
For example:
[1,2,3].supply(myFunc) yielding 6 if myFunc were the summation function.
It just seems easier to chain functions if I were able to do this, instead of calculating something and 'wrapping it' into an argument for a function call.
You can define it yourself if you want. It's frequently called the "pipe operator":
class AnyWrapper[A](wrapped: A) {
def |>[B](f: A => B) = f(wrapped)
}
implicit def extendAny[A](wrapped: A): AnyWrapper[A] = new AnyWrapper(wrapped)
Then:
def plus1(i: Int) = i + 1
val fortyTwo = 41 |> plus1
Do you mean something like this:
val sum = { (a: Int, b: Int) => a + b }
List(1, 2, 3).reduceLeft(sum)