我认为要找出正确的Lens
抽象,考虑具体的镜头类型会有所帮助。
然而,你的具体的例子,有一些东西我们可以说:
case class Lens[O[_],V[_],A,B](get: O[A] => V[A], set: (O[A],V[B]) => O[B])
我不认为这种镜头可以组成。为了组成镜片,get
的结果必须能够输入set
。但是在这里,get
的结果是V[_]
,而set
需要O[_]
。
作为进一步的解释,这里是另一个可能的一种多态的镜头,但它可能不是一个适合您的需要:
trait Lens[T[_]] {
def get[A](t: T[A]): A
def set[A,B](t: T[A], x: B): T[B]
}
它可以由像这样:
def composeLenses[T[_],U[_]](lens1: Lens[T], lens2: Lens[U]) =
new Lens[({type x[A] = T[U[A]]})#x] {
def get[A](t: T[U[A]]): A = lens2.get(lens1.get(t))
def set[A,B](t: T[U[A]], x: B): T[U[B]] = lens1.set(t, lens2.set(lens1.get(t), x))
}
我不可能抽象地弄清楚Lens
的定义 - 为了做到这一点,我不得不使用这个具体的案例:
case class Box[A](x: A)
def boxBoxGet[A](b: Box[Box[A]]): A = ???
def boxBoxSet[A,B](b: Box[Box[A]], x: B): Box[Box[B]] = ???