Scala “的通用容器类型(更高种类);“地图”;在斯卡拉
我试图定义一个用容器类型(更高种类)参数化的case类。此容器类型可以是任何类型,只要定义了映射方法即可 我希望通过以下代码实现此结果:Scala “的通用容器类型(更高种类);“地图”;在斯卡拉,scala,generics,higher-kinded-types,Scala,Generics,Higher Kinded Types,我试图定义一个用容器类型(更高种类)参数化的case类。此容器类型可以是任何类型,只要定义了映射方法即可 我希望通过以下代码实现此结果: import scala.language.higherKinds case class Test[A, C[A]](init: A, trans: Map[A,C[A]]) { def convert[B](conv: A => B): Test[B, C[B]] = { val _init = conv(init) val _t
import scala.language.higherKinds
case class Test[A, C[A]](init: A, trans: Map[A,C[A]]) {
def convert[B](conv: A => B): Test[B, C[B]] = {
val _init = conv(init)
val _trans = trans map {case (k,v) => (conv(k) -> (v map {x => conv(x)})}
Test(_init, _trans)
}
}
问题在于代码的v映射{x=>conv(x)}
部分。由于没有为C[A]
定义任何绑定,因此显然它不会编译
问题是,此容器类型可以是Id
(Scalaz样式,但使用map
而不是|>
),也可以是选项
,或者是集合(Seq
,Set
,List
,等等)
有没有办法告诉scala编译器容器类型必须有
map
方法?实现所需的最佳方法是使用type类。
例如,这里有一个使用的示例。(你也可以用同样的方法) 然而,如果出于某种原因您不能或不想使用Cats/Scalaz,您可以尝试
导入scala.language.higherKinds
导入scala.language.ReflectVeCalls
最终案例类测试[A,C[A]B:C[B]}(init:A,trans:Map[A,C[A]]){
def转换[B](转换:A=>B):测试[B,C]={
val_init=conv(init)
val_trans=trans-map{case(k,v)=>conv(k)->v.map(x=>conv(x))}
测试(_init,_trans)
}
}
尽管如此,请注意最后一个方法将适用于
选项,但对于列表
将失败,这很简单,因为列表中的映射
方法接收一个隐式的CanBuildFrom
,因此它不等于您想要的方法。实现您想要的最好方法是使用类型类。
例如,这里有一个使用的示例。
(你也可以用同样的方法)
然而,如果出于某种原因您不能或不想使用Cats/Scalaz,您可以尝试
导入scala.language.higherKinds
导入scala.language.ReflectVeCalls
最终案例类测试[A,C[A]B:C[B]}(init:A,trans:Map[A,C[A]]){
def转换[B](转换:A=>B):测试[B,C]={
val_init=conv(init)
val_trans=trans-map{case(k,v)=>conv(k)->v.map(x=>conv(x))}
测试(_init,_trans)
}
}
尽管如此,请注意最后一个方法将适用于选项
,但对于列表
,它将失败,原因很简单,因为列表中的映射
方法接收到一个隐式的CanBuildFrom
,因此它不等于您想要的方法。functor类型类如何?functor类型类如何?谢谢,路易斯·米格尔。但是,如果你能再帮我一点的话。我没有养猫的经验。当我尝试应用您的示例并实例化测试类时,我收到以下错误消息:无法找到参数CFunctor:cats.Functor[Set]
的隐式值。我猜我必须提供隐式参数,但是我该怎么做呢?嗨@Jeff,简单的方法是只导入cats.implicits.\u
,这将几乎所有库都包含在范围内。或者,如果您只需要set的Functor,您可以从cats.instances.set.\u
获取它,它将为set
带来所有隐式实例,包括Functor[set]。要了解更详细的解释,请阅读。谢谢你,路易斯·米格尔。但是,如果你能再帮我一点的话。我没有养猫的经验。当我尝试应用您的示例并实例化测试类时,我收到以下错误消息:无法找到参数CFunctor:cats.Functor[Set]
的隐式值。我猜我必须提供隐式参数,但是我该怎么做呢?嗨@Jeff,简单的方法是只导入cats.implicits.\u
,这将几乎所有库都包含在范围内。或者,如果您只需要set的Functor,您可以从cats.instances.set.\u
获取它,它将为set
带来所有隐式实例,包括Functor[set]。有关更详细的说明,请阅读。
import scala.language.higherKinds
import cats.Functor
import cats.syntax.functor.toFunctorOps
final case class Test[A, C[_]](init: A, trans: Map[A,C[A]])(implicit CFunctor: Functor[C]) {
def convert[B](conv: A => B): Test[B, C] = {
val _init = conv(init)
val _trans = trans map { case (k,v) => conv(k) -> v.map(x => conv(x)) }
Test(_init, _trans)
}
}
import scala.language.higherKinds
import scala.language.reflectiveCalls
final case class Test[A, C[A] <: { def map[B](f: A => B): C[B]}](init: A, trans: Map[A,C[A]]){
def convert[B](conv: A => B): Test[B, C] = {
val _init = conv(init)
val _trans = trans map { case (k,v) => conv(k) -> v.map(x => conv(x)) }
Test(_init, _trans)
}
}