代码之家  ›  专栏  ›  技术社区  ›  bbarker

有没有办法保证Scala中存在类型类方法?

  •  1
  • bbarker  · 技术社区  · 6 年前

    在下面的例子中,我有一个类型类 Foo ,并希望以某种方式保证所有符合 (如 Bar 通过 barFoo )有一个复制方法,例如通过 case class 是的。我还没想到办法。在这种情况下,副本签名可能是 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
      }
    }
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Sebastian Celestino    6 年前

    我不能用类型成员来做,但是这里有一个带有类型参数的版本。还需要向foo添加一个方法来构造对象。

    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)