Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typed Function and Currying in Scala

Tags:

scala

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
like image 811
reikje Avatar asked Feb 17 '14 10:02

reikje


People also ask

What is function currying in Scala?

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.

What is the difference between currying and partial application?

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.

What is the meaning of => in Scala?

=> 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 .

What is the difference between method and function in Scala?

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.


2 Answers

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...
like image 64
senia Avatar answered Sep 23 '22 23:09

senia


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
like image 21
Kevin Wright Avatar answered Sep 21 '22 23:09

Kevin Wright