0

Question

How to convert the method timed into a function?

val timing = new StringBuffer
def timed[T](label: String, code: => T): T = {
  val start = System.currentTimeMillis()
  val result = code
  val stop = System.currentTimeMillis()
  timing.append(s"Processing $label took ${stop - start} ms.\n")
  result
}

Below causes "error: not found: type T"

val timing = new StringBuffer
val timed: (String, => T) => T = (label, code) => {
    val start = System.currentTimeMillis()
    val result = code
    val stop = System.currentTimeMillis()
    timing.append(s"Processing $label took ${stop - start} ms.\n")
    result
}

2 Answers 2

3

There is no such thing as generic function in Scala (and generic value at all), only generic methods are.

Generic functions will appear in Scala 3.

https://github.com/lampepfl/dotty/pull/4672

http://dotty.epfl.ch/docs/reference/overview.html#new-constructs

val timing = new StringBuffer
val timed: [T] => (String, /*=>*/ T) => T = [T] => (label: String, code: /*=>*/ T) => {
  val start = System.currentTimeMillis()
  val result = code
  val stop = System.currentTimeMillis()
  timing.append(s"Processing $label took ${stop - start} ms.\n")
  result
}

in Dotty 0.20.0-RC1.

Sign up to request clarification or add additional context in comments.

Comments

3

Scala doesn't have polymorphic functions.

Let me use an example from an excellent blog post by Miles Sabin:

def singleton[T](t: T) = Set(t)

// eta-expanded to Int => Set[Int]
List(1, 2, 3) map singleton

// eta-expanded to String => Set[String]
List("foo", "bar", "baz") map singleton

Method singleton() gets eta-expanded into a function at the point of usage, and at that point its types are fixed into inferred concrete types. So it can easily "become" (be expanded into) a function Int => Set[Int] or String => Set[String], but cannot stay something like T => Set[T]. There's no built-in way of expressing polymorphic functions in the language itself (Scala 3 might change that).

However, there is a way to have polymorphic functions via natural transformations and/or shapeless's Poly with a bit of type gymnastics. Both are based on the same principle of encoding the function as a trait with higher kinded types for input/output and having a generic apply[T]() method with an independent type T which is fixed to a different concrete type every time the function is invoked (in our case those would be Int, String etc.).

Something like this:

trait PolymorphicFunction[F[_], G[_]] {
  def apply[T](f: F[T]): G[T]
}

But instead of attempting to explain it in details here, I would rather refer you to shapeless documentation and the aforementioned short series of blog posts.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.