[英]Scala: Multiple type parameters for implicit class
我正在尝试将Haskell库的某些部分用于数据类型通用编程移植到Scala。 这是我遇到的问题:
我用一个容器类型的参数定义了特征Generic
:
trait Generic[G[_]] {
// Some function declarations go here
}
现在,我有了一个抽象类Collect
,它带有三个类型参数和一个函数声明(它表示一个类型,可以将类型B
所有子值从类型A
某些结构收集到类型F[_]
的容器中):
abstract class Collect[F[_],B,A] {
def collect_ : A => F[B]
}
为了使它扩展泛型,给出了前两个类型参数F[_]
和B
,并且对A
进行了咖喱(使用lambda类型模拟此效果):
class CollectC[F[_],B] extends Generic[({type C[A] = Collect[F,B,A]})#C] {
// Function definitions go here
}
问题是我需要隐式最后一个类定义,因为稍后在代码中,我将需要能够编写类似
class GUnit[G[_]](implicit gg: Generic[G]) {
// Some definitions
}
当我简单implicit
将implicit
到类定义之前时,我得到一个错误,提示implicit classes must accept exactly one primary constructor parameter
。 有没有人遇到过类似的问题? 有已知的解决方法吗? 我目前看不到如何在保持相同功能的情况下重构代码,因此欢迎您提出任何建议。 提前致谢!
隐式类不能那样工作。 它们是隐式转换的简写。 例如, implicit class Foo(i: Int)
等于class Foo(i: Int); implicit def Foo(i: Int) = new Foo(i)
class Foo(i: Int); implicit def Foo(i: Int) = new Foo(i)
。 因此,它仅适用于在其构造函数中仅具有一个参数的类。 对于大多数0参数(类型)类而言,这没有意义。
您的问题的标题似乎还表明您认为编译错误是在谈论类型构造函数的类型参数,但我希望以上段落也清楚地表明,它实际上是在谈论价值构造函数的值参数。
对于您想做的事情(我认为),您必须自己提供一个CollectC
的隐式实例。 我建议将其放在Collect
的伴随对象中。 但是,如果您更适合您,则可以选择其他解决方案 。
scala> :paste
// Entering paste mode (ctrl-D to finish)
trait Generic[G[_]] {
// Some function declarations go here
}
abstract class Collect[F[_],B,A] {
def collect_ : A => F[B]
}
object Collect {
implicit def mkCollectC[F[_],B]: CollectC[F,B] = new CollectC[F,B]
}
class CollectC[F[_],B] extends Generic[({type C[A] = Collect[F,B,A]})#C] {
// Function definitions go here
}
// Exiting paste mode, now interpreting.
warning: there were four feature warnings; for details, enable `:setting -feature' or `:replay -feature'
defined trait Generic
defined class Collect
defined object Collect
defined class CollectC
scala> implicitly[Generic[({type C[X] = Collect[List,Int,X]})#C]]
res0: Generic[[X]Collect[[+A]List[A],Int,X]] = CollectC@12e8fb82
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.