Scala doobie片段与泛型类型参数

时间:2018-02-17 02:47:12

标签: sql scala doobie

我正在尝试将不同类型的对象插入到类似结构的sql表中。这就是我要做的事情:

class TableAccess[A : Meta](table: String) {
  def insert(key: String, a: A): ConnectionIO[Unit] = {
    (fr"insert into " ++ Fragment.const(table) ++ fr" values ($key, $a);").update.run.map(_ => ())
  }
}

但是我得到了这个编译错误:

[error] diverging implicit expansion for type doobie.util.param.Param[A]
[error] starting with method fromMeta in object Param
[error]     (fr"insert into " ++ Fragment.const(table) ++ fr" values ($key, $a);").update.run.map(_ => ())

我在文档中找到的只有:

  

doobie允许您插入任何类型的值(和选项)   其中包含一个Meta实例,包括......

但在这种情况下似乎还不够;我需要什么样的类型类/进口/转换?

3 个答案:

答案 0 :(得分:1)

大约一年后,我将回答我自己的问题。我从来没有完全了解正在发生的事情,并且从那以后我已经更新到了新版本的doobie,所以我不确定这有多重要。但是现在文档包含以下线索:

注意:重要的是要了解Meta仅存在于引入 获取/将对放入隐式范围。您不应该要求Meta为 用户代码中的证据:相反,要求获取,放置或两者兼有。

def foo[A: Meta](...)     // don't do this
def foo[A: Get: Put](...) // ok

事实上,在更改和新版本之间,现在可以对我进行编译了:

class TableAccess[A: Get: Put](table: String) {

答案 1 :(得分:0)

当编译器解析隐式时,它会搜索当前作用域中特定类型之一。在他的树搜索中,他似乎发现了不止一个。

这不是一个缺少类型类或导入的问题,它更像是你有太多它们而且编译器无法找到正确的类型。 尝试删除一些隐式的,看看它是如何工作的或明确地传递它们。

答案 2 :(得分:0)

我解决此问题的一种方法是将类型参数(及其证据)本地化到方法上(在静态/伴侣对象上),然后对其进行编译。

类似

object MinimalGood {
  def good[A: Meta, B: Meta](a: A, b: B): Update0 =
  sql"""$a $b""".update
}