Archeg
Archeg

Reputation: 8462

Can we call scala functions polymorphic by parameter without shapeless

I'm talking about this (and only about parametric polymorphism):

def fun1[T](s: Set[T]): Option[T] = s.headOpton

I've seen in a few places when people call this an example of polymorphic function around T in raw scala - something like in shapeless Set ~> Option.

But I do not understand why we can call it polymorphic. Even though we seem to be able to pass there both Set[Int] and Set[String] in reality fun1[Int] and fun1[String] are two different functions. I think I can claim that because eta-expansion of fun1 is wrong and does not give us what we want:

scala> fun1 _
res0: Set[Nothing] => Option[Nothing] = <function1>

And we need to always mention a type when we expand:

scala> fun1[Int]_
res1: Set[Int] => Option[Int] = <function1>

I am trying to study shapeless and I try to compare it with the raw scala - that's where the question is coming from. Do I understand it correctly?

Upvotes: 4

Views: 200

Answers (1)

Filippo Vitale
Filippo Vitale

Reputation: 8103

fun1 implementation is not dependent on the type T therefore it is written generically:

Using parametric polymorphism, a function or a data type can be written generically so that it can handle values identically without depending on their type.

(source Wikipedia)

I agree when you mention that fun1[Int] and fun1[String] "are two different functions". These are adopting a "concrete type":

Parametric polymorphism refers to when the type of a value contains one or more (unconstrained) type variables, so that the value may adopt any type that results from substituting those variables with concrete types.

(source Haskell wiki)


EDIT after @Travis and @Miles comments:

As Travis clearly explained, we can have polymorphic methods in "plain scala" but not polymorphic functions. In this article Miles implements using Poly exactly the polymorphic function mentioned in this question:

object headOption extends PolyFunction1[Set, Option] {
  def apply[T](l: Set[T]): Option[T] = l.headOption
}

scala> headOption(Set(1, 2, 3))
res2: Option[Int] = Some(1)

Upvotes: 2

Related Questions