Reputation: 1356
I am new with scala generics, I have read multiple articles about views, type bound/context bound. When I have tried to implement my class, I was really confused.
My question is, let's say I have a template class MyClass[T]{}. I want that T must have some methods for example :
def func1(t:T):T
def func2(t:T):Boolean
def func3(t:T):Unit
Note: classes that will use MyClass are not T therefore I cannot use :< or :>
I have read about Ordered and Ordering that have implicit function, but I still cannot figure out how to implement it.
Thanks for helpers
Upvotes: 0
Views: 685
Reputation: 24413
You can do that with typeclasses. Create a trait
, that contains the methods you need and for every type that should be supported create an implicit instance:
trait MyTypeClass[T] {
def func1(t:T):T
def func2(t:T):Boolean
def func3(t:T):Unit
}
implicit object MyTypeClassInt extends MyTypeClass[Int] {
def func1(t:Int) = t + 2
def func2(t:Int) = t > 4
def func3(t:Int) = println(s"t is: $t")
}
Now if you add a context bound to the type parameter in your class, it can only be instantiated, when an instance for the given type is in scope.
class MyClass[A : MyTypeClass](a: A)
scala> new MyClass(2)
res0: MyClass[Int] = MyClass@47825164
scala> new MyClass("")
<console>:11: error: could not find implicit value for evidence parameter of type MyTypeClass[String]
new MyClass("")**
You can access the instance in your class by calling implicitly[MyTypeClass[A]]
. Alternatively you can do one of the following things:
1.) Instead of using a context bound add an implicit parameter to your class:
class MyClass[A](a: A)(implicit ev: MyTypeClass[A])
2.) Add a companion for your typeclass, that has an apply method, that implicitly retrieves the instance and returns it:
object MyTypeClass {
def apply[A](implicit ev: MyTypeClass[A]) = ev
}
and use it in your class like this:
MyTypeClass[A].func1(a)
Upvotes: 1