貓和狗都是寵物,因此有一個年齡。我想定義一種chooseOldest方法,給定兩只貓或兩只狗,它將選擇最古老的寵物,但當同時出現貓和狗時,它將拒絕選擇。
用 typeclasses 實作的 Semigroups 似乎讓我完成了 90% 的作業,但我不知道是否可以定義chooseOldest 一次;理論上,由于所有Pets 都有一個年齡,因此不需要為 each 實作它Pet,但實際上我無法弄清楚如何只定義一次,同時仍然回傳子類的型別并保留“貓狗不” t 混合”規則:
trait Pet {
def age: Int
// When implementation is shared, it *doesn't* return the subclass type
def _chooseOldest(rhs: Pet): Pet = if (age > rhs.age) this else rhs
}
case class Dog(age: Int) extends Pet
case class Cat(age: Int) extends Pet
trait Semigroup[A] {
def chooseOldest(lhs: A, rhs: A): A
}
// When the implementation returns the subclass type, it can't be shared
implicit val dogSemigroup = new Semigroup[Dog] {
override def chooseOldest(lhs: Dog, rhs: Dog): Dog = if (lhs.age > rhs.age) lhs else rhs
}
implicit val catSemigroup = new Semigroup[Cat] {
override def chooseOldest(lhs: Cat, rhs: Cat): Cat = if (lhs.age > rhs.age) lhs else rhs
}
def chooseGeneric[P <: Pet](p1: P, p2: P)(implicit ev: Semigroup[P]): P = ev.chooseOldest(p1, p2)
def canChooseDogs(d1: Dog, d2: Dog)(implicit ev: Semigroup[Dog]): Dog = chooseGeneric(d1, d2)(ev)
def canChooseCats(c1: Cat, c2: Cat)(implicit ev: Semigroup[Cat]): Cat = chooseGeneric(c1, c2)(ev)
// Appropriately errors because there is no Semigroup[Pet]
def cantMixCatsAndDogs(c: Cat, d: Dog)(implicit ev: Semigroup[Pet]): Pet = chooseGeneric(c, d)(ev)
如果我無法弄清楚這一點,我將在接下來嘗試F-bounded polymorphism,但我懷疑這里有一個我缺少的解決方案,因為這是我第一次涉足型別類。
是否可以使用型別類來實作 3 個給定的要求?
- 貓狗不能“結合”
chooseOldest有一個單一的實作- 存在一個
chooseOldest回傳子型別別
uj5u.com熱心網友回復:
你可以這樣做:
sealed trait Pet {
def age: Int
}
object Pet {
final case class Dog(age: Int) extends Pet
final case class Cat(age: Int) extends Pet
sealed trait ChooseOldest[P <: Pet] {
def apply(p1: P, p2: P): P
}
object ChooseOldest {
given instance[P <: Pet](using NotGiven[P =:= Pet]): ChooseOldest[P] with
override def apply(p1: P, p2: P): P =
if (p1.age > p2.age) p1 else p2
}
extension [P <: Pet](self: P)(using ev: ChooseOldest[P])
def chooseOldest(other: P): P =
ev(self, other)
}
請注意,這NotGiven[P =:= Pet]是確保不會有允許混合型別的實體的原因。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/474438.html
上一篇:scala在元組2串列中添加_2
下一篇:獲取案例類引數型別作為HList
