Given:
scala> sealed trait Father
defined trait Father
scala> case object Son extends Father
defined object Son
and a type-class:
scala> trait Foo[A]
defined trait Foo
Next, I defined the function, f, which, as I understand it, expects the type parameter, A, to be a sub-class of Father and have a typeclass instance of Foo.
scala> def f[A <: Father : Foo](x: Father): String = x.toString
f: [A <: Father](x: Father)(implicit evidence$1: Foo[A])String
Then, I defined an instance:
scala> implicit val fooFather = new Foo[Father] {}
fooFather: Foo[Father] = $anon$1@4f25b795
And lastly I called it:
scala> f(Son)
res0: String = Son
However, it seems to me that f could've been written as:
def f[A <: Father](x: Father)(implicit ev: Foo[A]): String = x.toString
Is there a preferred way of writing the above function f? And, is there a difference between them?
fclearly shows they are the same.