2015-07-14 2 views
4

Это продолжение к моему предыдущему questionПочему в Scalaz нет полугруппы no> => для A => M [A]?

Kleisli определяет два оператора <=< (составляет) и >=> (andThen). >=> выглядит очень естественно для меня, и я не понимаю, как полезно использовать <=<.

Кроме того, похоже, что нет >=> полугруппы для A => M[A], но <=< полугруппа действительно существует.

В чем причина этого?

+1

Я подозреваю, что единственным реальным ответом является математическая традиция. Эти два эквивалентны в том, что 'a <=< b == b > => a', no? Так что это просто конвенция, например, например. матричное умножение определяется как row-column, а не row-row. – lmm

ответ

7

compose (или <=<) является немного более естественным при переводе между точечными и без точечными стилями. Например, если у нас есть эти функции:

val f: Int => Int = _ + 1 
val g: Int => Int = _ * 10 

мы получаем следующие эквивалентности:

scala> (f andThen g)(3) == g(f(3)) 
res0: Boolean = true 

scala> (f compose g)(3) == f(g(3)) 
res1: Boolean = true 

В compose случае f и g находятся в том же порядке, по обе стороны уравнения.

К сожалению, тип вывода Scala часто делает andThen (или >=>) более удобным, и он, как правило, более широко используется, чем compose. Таким образом, это случай, когда математические условности и причуды системы вывода типа Scala имеют разногласия. Скалаз (не слишком удивительно, учитывая культуру проекта) выбирает математическую сторону.

+0

Спасибо, я вижу смысл. Мне интересно, как реализовать что-л. например: предположим, что у меня есть функция 'child (name: String): XmlNode => Option [XmlNode]'. Я хотел бы написать «Список (« a »,« b »,« c »). Map (name => child (name)). FoldMap (...)', чтобы получить функцию, которая возвращает узел по пути ' "а/б/с" '. И теперь мне нужно отменить список :(который кажется полностью избыточным. « – Michael

+0

Да, это случай, когда'> => ', похоже, более близко соответствует тому, что делает операция. Я бы, вероятно, пропустил моноид и использовал' > => 'непосредственно. –

+0

В качестве альтернативы можно было бы просто определить такой моноид:« Monoid.instance (_> => _, {node => Some (node)}) '(не уверен, как это сделать правильно еще) и передать его в 'foldMap'. Вероятно, я задам новый вопрос. – Michael

Смежные вопросы