I'm trying to write a generic repository module that can handle a varying number of keys
trait Repo[K, V] {
def read(key: K): V
}
trait DynamoDBRepo extends Repo[K,V]{
def aRepo[K:StringIdentifiable,V]() = new Repo[K,V]{
val dynamoDBClient = ???
override def read(key: K, tableName: String): V = {
val tableKey: String = implicitly[StringIdentifiable].identify(key)
dynamoDBClient.Table(tableName).get(tableKey) //(*)
}
}
}
@typeclass trait StringIdentifiable[M] {
def identify(id: M): String
}
(*) However, dynamoDBClient.Table(tableName).get(key)
can also take a tuple as a key (partition key and sort key).
Therefore, I want to somehow extract String from K or (String, String) from (K,K) from key:K override def read(key: K)
I first tried this to extract types from a tuple that implements a StringIdentifiable typeclass. I got stuck.
Then tried to rewrite a StringIdentifiable type class, that would return String when the argument was one key but (String, String) when the argument to the read was a tuple. But I was not able to use this method either.
How can I solve his problem without losing my abstraction