1

This is potentially super easy, but I can't find any documentation on my problem.
There are two ways to define a functions in Scala, one with the def and the other with the val keyword. As an adept in functional programming, I'd like to use the latter more.

Now I have a problem: It's no problem to write a def function with a polymorphic type parameter:

def function[T](n: T) = {print(n)} // syntactically fine

How to do the same thing with the val keyword still eludes me though. This naive approach is syntactically invalid:

val function[T]: (a: T) => print(a) // Doesn't compile

That said, it is absolutely possible that I misunderstand Scala's approach on polymorphism and generics here.

1
  • 1
    Actually the first statement is wrong, def creates methods, not functions. And actually what you asked is a FAQ search there for "difference between functions and methods"_ - TL;DR; what you want is not possible in Scala 2 but will be in Scala 3. Commented Jan 10, 2021 at 13:57

2 Answers 2

6

In Scala 2 it is impossible to define parametric function, only method.

In Scala 3 polymorphic function type is introduced:

val fun: [A] => A => Unit = [A] => a => println(a.toString)

Workaround used in 2 by Cats and friends were traits with polymorphic apply

trait MySpecialFunctionlikeThing {
  def apply[A](a: A): Unit
}

Unfortunately, single abstract method (SAM) doesn't work with things like that, so some tricks were used to make it easy to lift function into such methods:

object MySpecialFunctionlikeThing {

  type Arbitrary

  def lift(f: Arbitrary => Unit): MySpecialFunctionlikeThing =
    new MySpecialFunctionlikeThing {
      def apply[A](a: A): Unit = f(a.asInstanceOf[Arbitrary])
    }
}

val fun = MySpecialFunctionlikeThing.lift(a => println(a))

The latter I saw in several different forms: the above, one using existential types and one using one of the above for method signature and macro for implementation (see FunctionK.lift).

Quite often, though, you can get away with what you used that is parametric, nullary method returning non-parametric function.

def fun[A]: A => Unit = a => println(a)
Sign up to request clarification or add additional context in comments.

Comments

1

This would require higher-rank types, which isn't supported in Scala 2.

It is supported in Scala 3: https://dotty.epfl.ch/docs/reference/new-types/polymorphic-function-types.html

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.