Как исправить это упражнение с помощью Endomorphic wrapper?
Это продолжение моего предыдущего вопроса.
Предположим, мне нужно найти узел XML по пути. Я могу написать функцию, чтобы получить дочерний узел по имени
import scala.xml.{Node => XmlNode}
def child(name: String): XmlNode = Option[XmlNode] = _.child.find(_.label == name)
Я сочиняю 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
Не могли бы вы помочь найти ошибку?
1 ответ
Решение
В первом примере вы пишете слева направо (>=>
).
Но Endomorphic
вызывает compose
метод(иначе<=<
), который работает справа налево.
Таким образом, ваш второй пример будет захватывать<a1>
сначала ищите<a0>
внутри того, что явно терпит неудачу.
Есть два способа восстановить поведение слева направо. Вы можете перевернуть список перед тем, как свернуть его, или обернуть каждый элемент вDual
,