使用方法名编写泛型函数
writing generic function using method name
我正在尝试编写以下方法:
case class Config2(repoName: String)
def buildAction[A, M, R <: HList]()
(implicit
gen: Generic.Aux[Config2, R],
mod: Modifier.Aux[R, M, A, A, R])
: (A, Config2) => Config2 = {
(arg: A, c: Config2) => {
val rec = mod.apply(gen.to(c), _ => arg)
gen.from(rec)
}
}
尝试将其用于:
buildAction[String, Witness.`'repoName`.T, String :: HList]()
我得到一个错误:
could not find implicit value for parameter gen: shapeless.Generic.Aux[com.advancedtelematic.tuf.cli.Cli.Config2,shapeless.::[String,shapeless.HList]]
[error] val _ = buildAction[String, Witness.`'repoName`.T, String :: HList]()
我是不是遗漏了一些导入信息?
第二个问题是,我能否以某种方式重写此签名,这样我就不必指定所有类型?实际上,Config2 类型需要一长串字段,所以一直写这个是不切实际的
更新:
我将其简化为以下内容:
val CGen = LabelledGeneric[Config]
def buildAction[A, M]()
(implicit mod: Modifier.Aux[CGen.Repr, M, A, A, CGen.Repr])
: (A, Config) => Config = {
(arg: A, c: Config) => {
val rec = mod.apply(CGen.to(c), _ => arg)
CGen.from(rec)
}
}
这让我可以写:
buildAction[String, Witness.`'repoName`.T]()
但我仍然必须指定Witness
。我可以这样写 buildAction[String]("repoName")
并让一些方法隐式提供 Witness 吗?
更新:以下作品!
val CGen = LabelledGeneric[Config]
def buildAction[A](witness: Witness)
(implicit mod: Modifier.Aux[CGen.Repr, witness.T, A, A, CGen.Repr]):
(A, Config) => Config = {
(arg: A, c: Config) => {
val rec = mod.apply(CGen.to(c), _ => arg)
CGen.from(rec)
}
}
buildAction[RepoName]('repoName)
am I missing some import here?
不是,可能只是 String :: HList
必须是 String :: HNil
Second question is, can I somehow rewrite this signature so I don't don't have to specify all the types?
你可以使用一个技巧kinda-curried type parameters:
object buildAction {
class PartiallyApplied[A, M] {
def apply[R <: HList]()(implicit ...)
}
def apply[A, M] = new PartiallyApplied[A, M]
}
用作
buildAction[String, Witness.`'foo`.T]()
此外,由于您的代码提到了字段名称,您可能希望 LabelledGeneric
与 ops.record.Updater
结合使用
我正在尝试编写以下方法:
case class Config2(repoName: String)
def buildAction[A, M, R <: HList]()
(implicit
gen: Generic.Aux[Config2, R],
mod: Modifier.Aux[R, M, A, A, R])
: (A, Config2) => Config2 = {
(arg: A, c: Config2) => {
val rec = mod.apply(gen.to(c), _ => arg)
gen.from(rec)
}
}
尝试将其用于:
buildAction[String, Witness.`'repoName`.T, String :: HList]()
我得到一个错误:
could not find implicit value for parameter gen: shapeless.Generic.Aux[com.advancedtelematic.tuf.cli.Cli.Config2,shapeless.::[String,shapeless.HList]]
[error] val _ = buildAction[String, Witness.`'repoName`.T, String :: HList]()
我是不是遗漏了一些导入信息?
第二个问题是,我能否以某种方式重写此签名,这样我就不必指定所有类型?实际上,Config2 类型需要一长串字段,所以一直写这个是不切实际的
更新:
我将其简化为以下内容:
val CGen = LabelledGeneric[Config]
def buildAction[A, M]()
(implicit mod: Modifier.Aux[CGen.Repr, M, A, A, CGen.Repr])
: (A, Config) => Config = {
(arg: A, c: Config) => {
val rec = mod.apply(CGen.to(c), _ => arg)
CGen.from(rec)
}
}
这让我可以写:
buildAction[String, Witness.`'repoName`.T]()
但我仍然必须指定Witness
。我可以这样写 buildAction[String]("repoName")
并让一些方法隐式提供 Witness 吗?
更新:以下作品!
val CGen = LabelledGeneric[Config]
def buildAction[A](witness: Witness)
(implicit mod: Modifier.Aux[CGen.Repr, witness.T, A, A, CGen.Repr]):
(A, Config) => Config = {
(arg: A, c: Config) => {
val rec = mod.apply(CGen.to(c), _ => arg)
CGen.from(rec)
}
}
buildAction[RepoName]('repoName)
am I missing some import here?
不是,可能只是 String :: HList
必须是 String :: HNil
Second question is, can I somehow rewrite this signature so I don't don't have to specify all the types?
你可以使用一个技巧kinda-curried type parameters:
object buildAction {
class PartiallyApplied[A, M] {
def apply[R <: HList]()(implicit ...)
}
def apply[A, M] = new PartiallyApplied[A, M]
}
用作
buildAction[String, Witness.`'foo`.T]()
此外,由于您的代码提到了字段名称,您可能希望 LabelledGeneric
与 ops.record.Updater