fetch icon indicating copy to clipboard operation
fetch copied to clipboard

DataCache trait doesn't allow to use bounds and typeclasses on keys and values

Open DenisNovac opened this issue 3 years ago • 1 comments

Hi everyone. I am having troubles using this trait:

trait DataCache[F[_]] {
  def lookup[I, A](i: I, data: Data[I, A]): F[Option[A]]

  def insert[I, A](i: I, v: A, data: Data[I, A]): F[DataCache[F]]
}

I want to use it with some underlying Cache[F[_], K:Hash, V] where K is my key and have implementation of cats' Hash. The problem is i can't do something like this:

class MyFetchCache[F[_], K: Hash, V](underlying: Cache[F, K, V]) extends DataCache[F] {
  def lookup[I, A](i: I, data: Data[I, A]): F[Option[A]] = underlying.put(i) // need to cast
  def insert[I, A](i: I, v: A, data: Data[I, A]): F[DataCache[F]] = underlying.put(i, v) // need to cast
}
class MyFetchCache[F[_], K, V](underlying: Cache[F, K, V]) extends DataCache[F] {
  def lookup[I: Hash, A](i: I, data: Data[I, A]): F[Option[A]] = underlying.get(i) // doesn't apply to interface
  def insert[I: Hash, A](i: I, v: A, data: Data[I, A]): F[DataCache[F]] = underlying.put(i, v) // doesn't apply to interface
}

I believe that my best option is to do something like this:

trait Data[I, A] 

class MyData[I: Hash, A] extends Data[I, A] {
   def hash(i: I) = Hash[I].hash(i)
}

class MyFetchCache[F[_], V](underlying: Cache[F, String, V]) extends DataCache[F] {
  def lookup[I, A](i: I, data: Data[I, A]): F[Option[A]] = {
   data match {
      case md: MyData => underlying.get(md.hash(i))
    }
  }
}

And even like this it seems that i'll need a lot of asInstanceOf casts.

DenisNovac avatar Feb 04 '22 12:02 DenisNovac

Hello, can you please share the exact compiler messages you are getting when trying to implement this? I'm having trouble seeing the source of the issue. The third block of code won't work as you can't change the interface, so that makes sense, but what is your return value from calling underlying.get/put? If the result value isn't the same, then yes you'll want to do some conversion or wrapping perhaps, depending on the type. Your second example should be a good starting point.

sloshy avatar Feb 16 '22 00:02 sloshy