Как исправить это упражнение с помощью 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,

Другие вопросы по тегам