So far i was under the impression that the only way to define Generic function in scala, was using Method e.g.
def myToString[A](value: A) = {println(value)}
However i figured the following way:
val myToStringFun: (T forSome {type T}) => Unit = value => println(value)
Is there something that i am not seeing or is that the pattern to write generic function in Scala without resorting to method ?
I never seen that pattern before, and only came up with it, based my learning around Higher-Kinded Type and the notion of existential ...
Please share your thoughts or wisdom on this....
EDIT1:
If the above is correct, why is it that this pattern is not used and people systematically resort to Method for generic function. Is it just a ease of notation
EDIT2:
If a function (T forSome {type T}) => Unit
<=> Any => Unit
It seems however that
val mySeqToString: (Seq[T] forSome {type T}) => String = {
case head +: tail => s"$head +: " + seqToString(tail)
case Nil => "Nil"
}
is equivalent to
def seqToString[T](seq: Seq[T]): String = seq match {
case head +: tail => s"$head +: " + seqToString(tail)
case Nil => "Nil"
}
correct ?
Type A
in your function is a standard generic type. You can do many things with it, such as demand a typeclass instance:
import cats.implicits._
def myToString[A: cats.Show](value: A) = { println(value.show) }
On the other hand, type (T forSome {type T})
is an existential type. You might recognize it by its more popular shorthand notation, _
(e.g. List[_]
). Not much you can do with that one. If you check the type of value
in
val myToStringFun: (T forSome { type T }) => Unit = value => println(value)
you will notice that it's Any
. BTW, using existential types via forSome
is being dropped.
Functions are monomorphic in Scala, unlike methods that are polymorphic. Personally, I think this article(s) provides a great explanation on that topic.
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