如何使用 Endomorphic wrapper 修复此练习?
How to fix this exercise with Endomorphic wrapper?
这是我之前 的后续。
假设我需要通过路径找到一个XML节点。我可以编写一个函数来通过名称
获取子节点
import scala.xml.{Node => XmlNode}
def child(name: String): XmlNode = Option[XmlNode] = _.child.find(_.label == name)
我用 kleisli 编写了 child
函数;例如
scala> val a = <a><a0><a1><a2/></a1></a0></a>
a: scala.xml.Elem = <a><a0><a1><a2/></a1></a0></a>
scala> val find01 = Kleisli(child("a0")) >=> Kleisli(child("a1"))
findAB: scalaz.Kleisli[Option,scala.xml.Node,scala.xml.Node] = Kleisli(<function1>)
scala> find01(a)
res85: Option[scala.xml.Node] = Some(<a1><a2/></a1>)
现在我正在使用内胚包装器,但它不起作用:
scala> List(child("a0"), child("a1")).foldMap(Endomorphic.endoKleisli[Option, XmlNode])
res93: scalaz.Endomorphic[[α, β]scalaz.Kleisli[Option,α,β],scala.xml.Node] = Endomorphic(Kleisli(<function1>))
scala> res93.run(a)
res94: Option[scala.xml.Node] = None
你能帮忙找出错误吗?
在第一个示例中,您是从左到右 (>=>
) 排版。
但是 Endomorphic
calls the compose
method (a.k.a. <=<
),它是从右到左工作的。
因此您的第二个示例将首先捕获 <a1>
,然后在其中寻找 <a0>
,这显然失败了。
有两种方法可以恢复从左到右的行为。您可以在折叠之前反转列表,或者将每个元素包装在 Dual
.
中
这是我之前
假设我需要通过路径找到一个XML节点。我可以编写一个函数来通过名称
获取子节点import scala.xml.{Node => XmlNode}
def child(name: String): XmlNode = Option[XmlNode] = _.child.find(_.label == name)
我用 kleisli 编写了 child
函数;例如
scala> val a = <a><a0><a1><a2/></a1></a0></a>
a: scala.xml.Elem = <a><a0><a1><a2/></a1></a0></a>
scala> val find01 = Kleisli(child("a0")) >=> Kleisli(child("a1"))
findAB: scalaz.Kleisli[Option,scala.xml.Node,scala.xml.Node] = Kleisli(<function1>)
scala> find01(a)
res85: Option[scala.xml.Node] = Some(<a1><a2/></a1>)
现在我正在使用内胚包装器,但它不起作用:
scala> List(child("a0"), child("a1")).foldMap(Endomorphic.endoKleisli[Option, XmlNode])
res93: scalaz.Endomorphic[[α, β]scalaz.Kleisli[Option,α,β],scala.xml.Node] = Endomorphic(Kleisli(<function1>))
scala> res93.run(a)
res94: Option[scala.xml.Node] = None
你能帮忙找出错误吗?
在第一个示例中,您是从左到右 (>=>
) 排版。
但是 Endomorphic
calls the compose
method (a.k.a. <=<
),它是从右到左工作的。
因此您的第二个示例将首先捕获 <a1>
,然后在其中寻找 <a0>
,这显然失败了。
有两种方法可以恢复从左到右的行为。您可以在折叠之前反转列表,或者将每个元素包装在 Dual
.