I have a class with an unknown number of functions:
class processors {
def p1(s: String): String = {
//code
}
def p2(s: String): String = {
//code
}
def p3(s: String): String = {
//code
}
...
}
I want to be able to run all the function one by one in the order they are written (p1 -> p2 -> p3 -> ...). Also, I would like to pass the initial string to p1, which will pass the result as the argument for p2 and do on. Is there a simple way to do that?
EDIT:
What I have so far:
At the moment I have a hard-coded sequence:
val processors = Seq(p1 _, p2 _, p3 _).reduce(_ andThen _)
processors(some_string)
I'd like to avoid the hard-coding, basically..
Reflection can help here. this example is for single param integer argument, but it can be extended to multiple arguments but it gets bit tricky dealing with types. Argument types can be queried from the class.
class A {
def f(x: Int): Int = 2 * x
def g(x: Int): Int = x * x
}
val clazz = classOf[A]
clazz.getDeclaredMethods.filter(! _.getName.contains("$"))
.map(x => {a: Integer => x.invoke(new A(), a: Integer).asInstanceOf[Integer] })
.reduce(_ andThen _)(new Integer(1))
For your case just replace Int with String
To maintain the order of execution of the functions in the class
try to put number in the function name and then order them by parsing string obtained from getName method
Related
IM trying to understand the below high order functions in Scala but need some clarifications on the parameters of the functions.
Questions:-
What does the Int => String in the apply function mean?
v: Int indicates that the parameter v is of type Int.
What does the [A](x: A) mean in layout function?
object Demo {
def main(args: Array[String]) {
println( apply( layout, 10) )
}
def apply(f: Int => String, v: Int) = f(v)
def layout[A](x: A) = "[" + x.toString() + "]"
}
f: Int => String means that f is a function with one argument of type Int and with a return type String
def layout[A](x: A) means that parameter x is of type A, which can be of any type. Here are a couple of examples on how to invoke layout:
layout[String]("abc") //returns "[abc]"
layout[Int](123) //returns "[123]"
When main runs it invokes apply with the layout function and the argument 10. This will output "[10]"
The syntax of Int => String means passing a function that accepts Int and returns String.
Here is a useful example for passing function:
case class Person(name: String, lastName: String)
val person = Person("Johnny", "Cage")
def updateName(name: String) = {
updatePerson(_.copy(name = name))
}
def updateLastName(lastName: String) {
updatePerson(_.copy(lastName = lastName))
}
private def updatePerson(transformer: Person => Person): Unit = {
transformer(person)
}
Note how each update function passes the copy constructor.
I am new to scala. I have worked on java. defining of function in scala by using = operator does not make sense for me.
def abc(a:Int,b:Int):Int =
a+b
can anybody explain? in the above code, why i had to use = operator.
I believe there are many reasons. Just some of them:
1) uniform access:
val abc: Int = 5 //value
def abc: Int = 5 //factory
Note that such def abc can be implemented with val abc inside successor:
trait Interface {
def abc: Int //factory (reader)
}
object Implementation extends Interface {
val abc: Int = 5 //singleton
}
Some advanced examples: Why it's impossible to override `var` with `def` in Scala?
2) functions are just named lambda's:
val abc = (a: Int, b: Int) => a + b //lambda assigned to abc value
def abc (a:Int, b:Int): Int = a + b //abc method, that could be converted to lambda/function with eta-expansion: "abc _"
The syntactic difference between first and second one is just position of braces, so they are quite similar.
3) that function actually returns value, you might think of the a + b block independently from function definition, so then:
def abc ...: Int = {
val z = a + b
z
}
is almost like
val abc: Int = {
val z = a + b
z
}
But a and b are unknown, so we need to describe them too:
def abc(a: Int, b: Int): Int = {
val z = a + b
z
}
Otherwise, if your method doesn't return anything, you can omit = sign:
def abc(a: Int, b: Int) {
println(a + b)
}
Which is equivalent to:
def abc(a: Int, b: Int): Unit = {
println(a + b)
}
Where Unit (inhabited type with only one possible value, so it contains no information) roughly means that no value was returned.
See also official doc and language spec
This approach enhances the functional aspect of programming, where functions are no different than other data types.
e.g. In Scala
val number = 10
val function = (a:Int, b:Int) => a + b
Here, both the values number and function are immutable variables. Only difference is their types. number is of type Int, while function is of type (Int, Int) => Int
This enables functions to be treated just like Data and be passed around like other variables. This enhances into concepts like Higher Order Functions which can accept and return function values as opposed to literal values. As #dk14 mentioned, it's about uniform access.
There is one reason I know why scala uses = in method declaration is:
To return any value from method definition ,= has to be used or it cant return any value even if there is a return statement in method.
For Eg: look at below two code snippets:
def method1()
{
val a=1
return a
}
def method2()=
{
val a=1
return a
}
method1 return type is always unit even if it returns some values
whereas method2 returns value a .
Google didn't help me with this question, I hope that doesn't mean it is not possible:
In my class I want to have a method that has a signature defined, but the body is not defined (method1)
There will be many defined methods that satisfy this signature (impl1, impl2, impl3)
When I initialise the object, I will then choose (based on some criteria) which method implementation impl1, impl2, impl3 to assign to the function pointer method1
Basically I'm asking how I can have a function pointer that can point to any function satisfying its signature.
EDIT:
So, it turns out it is actually very straight forward:
var method: Int => Int = (x => x+1)
method = (x => x-1)
method = (x => x*2)
etc...
My problem before was that I was using "val" or "def" to define "method"
Not sure why this wasn't suggested directly. Many people favoured the way of having the function as a parameter to some secondary class then initialise that class with a specific implementation. Maybe there is something that I'm missing.
EDIT 2: I realise now that I didn't get the answer I was looking for because I didn't word my question properly, I should have said that I wanted "delegate" behaviour as it is in C#.
In Scala, functions are objects, so you can do:
class Foo(val func : Int => Int){
}
object Main{
def main(args: Array[String]) {
val foo1=new Foo(x => x + 1)
val foo2=new Foo(x => x + 2)
val foo3=new Foo(x => x + 3)
println(foo1.func(10)) // Prints 11
println(foo2.func(10)) // Prints 12
println(foo3.func(10)) // Prints 13
}
}
And here is not-so-elegant approach with inheritance:
abstract class Foo() {
def say(): String
protected def bark = "Woof!"
protected def quack = "Quack!"
}
val dog = new Foo() {
def say() = bark
}
dog.say
// res2: String = Woof!
You mean like so:
class Whatever(selector: Int) {
type Signature = Int => String
private val implUsed = selector match {
case 1 => impl1
case _ => impl2
}
private val impl1: Signature = (i: Int) => i.toString
private val impl2: Signature = (i: Int) => i.toString + "_suffix"
def method: Signature = implUsed
}
You could obviously also write the impls as defs. Maybe a different approach based on inheritance may be preferrable though -- you may want to clarify what you are trying to achieve. While this approach is a literal solution to your request, it would be much more idiomatic to pass around the functions itself, like #Idan Arye suggested.
I would not use a method at all in this case. Just have a field that can be initialized to the specific function you want. Something like:
class Foo(val method1: Int => Int)
val doubler = new Foo(2*)
val incrementer = new Foo(1+)
val absolute = new Foo(_.abs)
val parity = new Foo(_ % 2)
val doesNothing = new Foo(identity)
doubler.method1(-3) // => -6
incrementer.method1(-3) // => -2
absolute.method1(-3) // => 3
parity.method1(-3) // => -1
doesNothing.method1(-3) // => -3
scala> def a(i:Int)(j:Int) = i * j
a: (i: Int)(j: Int)Int
scala> def b(i:Int, j:Int) = i * j
b: (i: Int, j: Int)Int
The two definitions are very similar, and they (appear to me) do the same thing.
Apart from defining a function which receives implicit parameters or a code block as parameter, is there any reason to use the first definition style?
This is the list I have compiled over the time:
1) Type resolution across multiple argument lists
class ResourceManager {
type Resource
def open: Resource = ???
}
class ResourceManagerTest {
// Does not compile: def test1(rm: ResourceManager, r: rm.Resource) = ???
// Compiles: This way the type can be resolved
def test2(rm: ResourceManager)(r: rm.Resource) = ???
}
2) Type inference where earlier arguments can "lock down" type parameters for later arguments (thanks to Myserious Dan)
def foo1[A](x: A, f: A => Int) = ???
def foo2[A](x: A)(f: A => Int) = ???
def foo1foo2Demo() {
// This will always demand a type annotation on any anonymous function
// you pass in:
foo1(1, (i: Int) => i * i)
// Does not compile: foo1(1, i => i * i)
// Type not required
foo2(2)(i => i * i)
}
3) Syntax-like language extensions
object MultipleArgumentListsDemo {
// This style of function definition allows syntax-like language extensions
#tailrec
def myWhile(conditional: => Boolean)(f: => Unit) {
if (conditional) {
f
myWhile(conditional)(f)
}
}
def myWhileDemo() {
var count = 0
myWhile(count < 5) {
count += 1
println(count)
}
}
4) Having both implicit and non implicit arguments, as implicit is a modifier for a whole argument list:
def f[A](x: A)(implicit mf: Manifest[A]) {
}
5) A parameter's value from one parameter list can be used to compute a default value in another parameter list, but not in the same one.
def g(x: Int)(y: Int = x * 2) = {
x + y
}
6) Multiple repeated argument lists ("varargs")
def h(as: Int*)(bs: Int*)(cs: Int*) = as.sum * bs.sum * cs.sum
7) Partial application
def i() {
val foop = h(1, 2, 3)(4, 5, 6, 7, 9) _
println(foop(Seq(10, 11)))
}
As I have not tracked my sources while I was compiling that list over the time: It's possible that some or all examples are copied from elsewhere (other questions on SO), so please drop a note, and I will add the reference as to where it came from.
The main reason for "currying" functions in this manner is to enable partial application:
scala> val c = a(5) _
c: Int => Int = <function1>
Here c is a function that takes a single int and returns the result of multiplying that int with 5. It may be that you would set up c in one method, and pass it into another method that expects a function taking one Int parameter. A bit trivial in this case, but very flexible for a range of uses.
Additional to support currying, it also helps with type inference: Sometimes the compiler can't infer the correct type if everything is in one argument list, but if you split off the part that depends on the binding of the other arguments, it works. A typical example is foldLeft: Try to implement it with one argument list, and then in some cases the compiler needs type annotations.
MWE (obs.: I am avoiding to have to instantiate a class every call of c, this is why functions are desired):
object Main extends App {
def a(s:String, i:Int) ={
s + i * i //some complex op that yields String
}
def b(i:Int) ={
i / 3 //another complex op that yields Int
}
def c(f: Any => Any) = {
val L = List(1,2,3,4) //list of complex elements
L map f //apply f within some complex loop
}
println(c(a))
/*
scala: type mismatch;
found : (String, Int) => String
required: Any => Any
println(c(a))
^
*/
println(c(b))
/*
scala: type mismatch;
found : Int => Int
required: Any => Any
println(c(b))
^
*/
}
Maybe an equivalent question would be "Is there some kind of function inheritance?",
like
def f
def fa(i: Int):String extends f
def fb(s: String):Int extends f
What you're trying to do isn't type-safe, since if it were you could pass a String to a function which takes an Int parameter:
e.g.
def c(f: Any => Any) = {
val L = List("a", "b", "c")
L map f
}
c(a)
However you can take a function of type Int => Any, since it is safe to assign a more derived type to Any.
def c(f: Int => Any) = {
val l = List(1,2,3,4)
l.map(f)
}
This is now safe:
val bList: List[Any] = c(b)
You still can't pass a to c however, since it requires two arguments instead of one. You can partially apply the first String argument and pass that:
val cList = c(a("SomeString", _:Int))
If you find yourself using Any,
you are probably doing something wrong, and
you most likely need generics.
In your case
def c[X,Y](f: X => Y) = { ... }
would probably do the trick, depending on what you have inside that complex loop.