有没有办法保证 Scala 中的类型类存在 case 类复制方法? [英] Is there a way to guarantee case class copy methods exist with type classes in Scala?
问题描述
在下面的示例中,我有一个类型类 Foo
,并且想以某种方式保证所有成员都符合 Foo
(例如 Bar
> 通过 barFoo
) 有一个复制方法,例如通过 case 类
生成的方法.我还没有想到这样做的方法.在这种情况下,复制签名可能类似于 copy(foo: F, aa: List[T] = foo.aa,maybe: Option[T] = foo.maybe): F
.
In the example below I have a type class Foo
, and would like to somehow guarantee that all members conforming to Foo
(such as Bar
via barFoo
) have a copy method such as the one generated by way of being a case class
. I haven't thought of a way to do this. In this case the copy signature would be possibly be something like copy(foo: F, aa: List[T] = foo.aa, maybe: Option[T] = foo.maybe): F
.
trait Foo[F] {
type T
def aa(foo: F): List[T]
def maybe(foo: F): Option[T]
}
final case class Bar(aa: List[String], maybe: Option[String])
object Bar {
implicit val barFoo = new Foo[Bar] {
type T = String
def aa(foo: Bar): List[String] = foo.aa
def maybe(foo: Bar): Option[T] = foo.maybe
}
}
推荐答案
我不能用类型成员来做,但这里有一个带有类型参数的版本.另外需要给Foo添加一个方法来构造对象.
I couldn't do it with type member, but here you are a version with type parameters. Also it is necessary to add a method to Foo to construct the object.
trait Foo[F, T] {
def aa(foo: F): List[T]
def maybe(foo: F): Option[T]
def instance(aa: List[T], maybe: Option[T]): F
}
class Bar(val aa: List[String], val maybe: Option[String]) {
override def toString = s"Bar($aa, $maybe)"
}
object Bar {
implicit val barFoo = new Foo[Bar, String] {
def aa(foo: Bar): List[String] = foo.aa
def maybe(foo: Bar): Option[String] = foo.maybe
def instance(aa: List[String], maybe:Option[String]):Bar = new Bar(aa, maybe)
}
}
implicit class FooOps[A, T](fooable:A)(implicit foo:Foo[A, T]) {
def copy(aa: List[T] = foo.aa(fooable), maybe: Option[T] = foo.maybe(fooable)) = {
foo.instance(aa, maybe)
}
}
val r = new Bar(List(""), Option("")).copy(aa = List("asd"))
println(r)
这篇关于有没有办法保证 Scala 中的类型类存在 case 类复制方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!