How to fix this exercise with Endomorphic wrapper?

天大地大妈咪最大 提交于 2019-12-20 03:28:07

问题


This is a follow-up to my previous question.

Suppose I need to find an XML node by path. I can write a function to get a child node by name

import scala.xml.{Node => XmlNode}

def child(name: String): XmlNode = Option[XmlNode] = _.child.find(_.label == name)

I compose the child functions with kleisli; e.g.

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>)

Now I am using the endomorphic wrapper but it doesn't work:

 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

Could you help to find the bug ?


回答1:


In the first example, you are composing left-to-right (>=>).

But Endomorphic calls the compose method (a.k.a. <=<), which works right-to-left.

So your second example would capture <a1> first, then look for <a0> inside that, which clearly fails.

There are two ways to recover the left-to-right behavior. You can reverse the list before folding it, or wrap each element in a Dual.



来源:https://stackoverflow.com/questions/31401343/how-to-fix-this-exercise-with-endomorphic-wrapper

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!