一日の終わりに、これが私が達成したいことです:
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")
}