简体   繁体   中英

Scala Generics - T has method restrictions

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

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM