如何使用 shapeless 将存储库客户端抽象为通用存储库模块
How to use shapeless to abstract a repository client into a generic repository module
我正在尝试编写一个可以处理不同数量的键的通用存储库模块
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
}
(*) 然而,dynamoDBClient.Table(tableName).get(key)
也可以 take a tuple 作为键(分区键和排序键)。
因此,我想以某种方式从 key:K override def read(key: K)
中从 K 中提取字符串或从 (K,K) 中提取 (String, String)
我首先尝试 从实现 StringIdentifiable 类型类的元组中提取类型。我卡住了。
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 .
我怎样才能在不失去抽象的情况下解决他的问题
如果问题的要求是您的解决方案必须满足的所有要求,那么根本不需要无形的、路径相关的类型和类型 类。
sealed trait RepoKey[K] // TBH I am not sure if genericness here is even needed in your case...
case class SimpleKey(key: K) extends RepoKey[K]
case class PartitionedKey(partition: K, key: K) extends RepoKey[K]
trait Repo[K, V] {
def read(key: RepoKey[K]): V
}
class DynamoDBRepo(dynamoDBClient: ...) extends Repo[String, V] {
def read(key: RepoKey[String]): V = key match {
case SimpleKey(key) => ...
case PartitionedKey(partition, key) => ...
}
}
即使您将密钥存储为 String
以外的其他内容,您唯一需要的类型类也将类似于:
trait KeyExtractor[K] {
def extract(key: RepoKey[K]): String
}
这几乎肯定不需要推导,但需要一个明确的定义。
我正在尝试编写一个可以处理不同数量的键的通用存储库模块
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
}
(*) 然而,dynamoDBClient.Table(tableName).get(key)
也可以 take a tuple 作为键(分区键和排序键)。
因此,我想以某种方式从 key:K override def read(key: K)
我首先尝试
我怎样才能在不失去抽象的情况下解决他的问题
如果问题的要求是您的解决方案必须满足的所有要求,那么根本不需要无形的、路径相关的类型和类型 类。
sealed trait RepoKey[K] // TBH I am not sure if genericness here is even needed in your case...
case class SimpleKey(key: K) extends RepoKey[K]
case class PartitionedKey(partition: K, key: K) extends RepoKey[K]
trait Repo[K, V] {
def read(key: RepoKey[K]): V
}
class DynamoDBRepo(dynamoDBClient: ...) extends Repo[String, V] {
def read(key: RepoKey[String]): V = key match {
case SimpleKey(key) => ...
case PartitionedKey(partition, key) => ...
}
}
即使您将密钥存储为 String
以外的其他内容,您唯一需要的类型类也将类似于:
trait KeyExtractor[K] {
def extract(key: RepoKey[K]): String
}
这几乎肯定不需要推导,但需要一个明确的定义。