0

一日の終わりに、これが私が達成したいことです:

  val onePath: One = new Log(OneLocation("root"), "foo/bar").getPath()
  val manyPath: Many = new Log(ManyLocation(List("base1", "base2")), "foo/bar").getPath()

それを実現するには、1 つまたは複数の値を表す ADT が必要なようです。

これが私の実装です。それを実装する別の/より良い/より簡単な方法はありますか(私はパス依存型とF-bounded型を使用しました)。すでにそれを実装しているライブラリはありますか (ユースケースはかなり最新のようです)。

  sealed trait OneOrMany[T <: OneOrMany[T]] {
    def map(f: String => String) : T
  }
  final case class One(a: String) extends OneOrMany[One] {
    override def map(f: String => String): One = One(f(a))
  }
  final case class Many(a: List[String]) extends OneOrMany[Many] {
    override def map(f: String => String): Many = Many(a.map(f))
  }

  sealed trait Location {
    type T <: OneOrMany[T]
    def value: T
  }

  final case class OneLocation(bucket: String) extends Location {
    override type T = One
    override val value = One(bucket)
  }
  final case class ManyLocation(buckets: List[String]) extends Location {
    override type T = Many
    override val value = Many(buckets)
  }

  class Log[L <: Location](location: L, path: String) {
    def getPath(): L#T = location.value.map(b => s"fs://$b/$path")
  }
4

3 に答える 3