来自示例的 scalaz 镜头不起作用

scalaz lens from example does not work

当我尝试使用 scalaz.7.2.15 中的 Lens.lensu 时,(我检查了 http://eed3si9n.com/learning-scalaz/Lens.html

case class Person(id: Int, name: String)

val idLens: Person @> Int = Lens.lensu(
  (p, id) => p.copy(id = id),
  _.id
)
val nameLens: Person @> String = Lens.lensu(
  (p, name) => p.copy(name = name),
  _.name
)

val c = idLens <=< nameLens

但我得到错误:

found   : Person @> String
[error]     (which expands to)   scalaz.LensFamily[Person,Person,String,String]
[error]  required: scalaz.LensFamily[?,?,Person,Person]
[error]     val c = idLens <=< nameLens

但是和示例一样,这段代码有什么问题?

您可以将 <=< 读为 "after"。那么

idLens <=< nameLens

表示:在nameLens之后使用idLens。为此,idLens 的 "input type"(即 Person)必须与 nameLens 的 "output type" 相匹配。这就是编译器期望 LensFamily[?,?,Person,Person](即输出类型 Person)的原因。但是nameLens的输出类型是String,不是Person.

您希望 c 拥有什么类型?如果要Person @> (Int, String),则使用并列组合:

val c = idLens *** nameLens