In Scala let's say I have a function like this:
def foo[R](x: String, y: () => R): R
so I can do:
val some: Int = foo("bar", { () => 13 })
Is there a way to change this to use function currying without "losing" the type of the second argument?
def foo[R](x: String)(y: () => R): R
val bar = foo("bar") <-- this is now of type (() => Nothing)
val some: Int = bar(() => 13) <-- doesn't work
Currying is the process of converting a function with multiple arguments into a sequence of functions that take one argument. Each function returns another function that consumes the following argument.
Simple answer. Currying: Lets you call a function, splitting it in multiple calls, providing one argument per-call. Partial Application: Lets you call a function, splitting it in multiple calls, providing multiple arguments per-call.
=> is syntactic sugar for creating instances of functions. Recall that every function in scala is an instance of a class. For example, the type Int => String , is equivalent to the type Function1[Int,String] i.e. a function that takes an argument of type Int and returns a String .
Difference between Scala Functions & Methods: Function is a object which can be stored in a variable. But a method always belongs to a class which has a name, signature bytecode etc. Basically, you can say a method is a function which is a member of some object.
Functions can't have type parameters, you have to use a custom class like this:
def foo(x: String) = new {
def apply[R](y: () => R): R = y()
}
val bar = foo("bar")
val some: Int = bar(() => 13)
// Int = 13
To avoid structural typing you could create custom class explicitly:
def foo(x: String) = new MyClass...
A variation on senia's answer, to avoid structural typing:
case class foo(x: String) extends AnyVal {
def apply[R](y: () => R): R = y()
}
val bar = foo("bar")
val some: Int = bar(() => 13)
// Int = 13
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With