Я экспериментирую с зависимыми от пути типами, и я сталкиваюсь с проблемой при попытке написать экземпляр scalaz.Equal
для него. У меня есть следующая структура:scalaz.Equal для зависимых от пути типов
class A {
class B
}
val a1 = new A
val b1 = new a1.B // type a1.B
val a2 = new A
val b2 = new a2.B //type a2.B
я первый хотел сделать b1
«unequalable» (это то, что слово?), Чтобы b2
во время компиляции, что я достиг со следующим:
import scalaz._
import Scalaz._
implicit def BEqual[X <: A#B]: scalaz.Equal[X] = Equal.equalA
b1 === b1 //true
b1 === b2 // doesn't compile, good
b2 === b1 // doesn't compile, good
Мои второй эксперимент был попытаться сделать равенство менее ограничительный характер, что позволяет экземпляры A#B
быть сопоставлены друг с другом, но не к другим типам, с:
implicit val BEqual: scalaz.Equal[A#B] = Equal.equalA
Но это не работает, как ожидалось:
b1 === b2 //doesnt' compile, === is not a member of a1.B
Это работает, однако:
BEqual.equal(b1,b2) //compiles
BEqual.equal(b1,"string") //doesnt' compile, good
Итак, я хотел бы знать, почему ===
не работает, и если я могу написать экземпляр от Equal
, который применим ко всем A#B
s?
Я попробовал решение для домашнего приготовления с неявным преобразованием, и это сработало.
implicit class abEqual(ab: A#B) {
def eqab(ab2: A#B) = ab == ab2
}
b1.eqab(b2) //ok
b2.eqab(b1) //ok
b1.eqab("String") //doesn't compile, good
Так почему это не работает с scalaz.Equal
?
"и' Equal' является инвариантным по параметру своего типа. Прямо там, это была деталь, которую я забыл! Я согласен, что я не хочу работать, это правильное поведение! Благодаря! – Chirlo