Reputation: 1281
I'm trying to write a generic implicit instance for the following structure :
object SmartHasher {
trait GetSmartHash[T] {
def calculateHash(value: T): Int
}
object syntax {
implicit class GetHashOps[T: GetSmartHash](itemToBeHashed: T) {
def hashItSmartway(implicit GetSmartHashInstance: GetSmartHash[T]): Int =
GetSmartHashInstance.calculateHash(itemToBeHashed)
}
}
object instances {
import syntax._
implicit def stringSmartHash: GetSmartHash[String] = (s: String) =>s.size % 10 // smart demo thing :D
}
Now I'm trying to define a generic implicit instance that works for any Vector, List, Or Array
where smarthash method for its elements are defined :
What type I shoud use instead of Seq , as Im trying with it and it doesnt work out ?
implicit def sequenceHash[T: GetSmartHash]: GetSmartHash[Seq[T]] =
(sequence: Seq[T]) => sequence.map(element => element.hashItSmartway).product
If I define It for an exact collection like Vector :
implicit def sequenceHash[T: GetSmartHash]: GetSmartHash[Vector[T]] =
(sequence: Vector[T]) => sequence.map(element => element.hashItSmartway).product
then it works as I expected. Any suggestions to write this in generic way for theese 3 collections, to prevent for repeating simillar code 3 times? Regards.
Upvotes: 0
Views: 197
Reputation: 51658
Try
object instances {
import syntax._
// stringSmartHash ...
implicit def sequenceHash[Col[X] <: Iterable[X], T: GetSmartHash]: GetSmartHash[Col[T]] =
(sequence: Col[T]) => sequence.map(element => element.hashItSmartway).product
}
Testing:
import instances._, syntax._
List("aa", "bbb").hashItSmartway //6
Seq("aa", "bbb").hashItSmartway //6
Vector("aa", "bbb").hashItSmartway //6
If you want sequenceHash
to work also for Array
replace upper bound with view bound
implicit def sequenceHash[Col[_], T: GetSmartHash](implicit ev: Col[T] => Iterable[T]): GetSmartHash[Col[T]] =
(sequence: Col[T]) => sequence.map(element => element.hashItSmartway).product
Upvotes: 2