Как использовать>=> в Scala?

Я пытаюсь использовать >=> (Стрелка Клейсли) в Скале. Как я понимаю, он состоит из функций, возвращающих монады. Сейчас я пытаюсь сделать это следующим образом:

scala> val f = {i: Int => Some (i + 1)}
f: Int => Some [Int] = scala> val g = {i: Int => Some (i.toString)}
g: Int => Some [String] = scala> val h = f> => g: 15: error: value> => не является членом Int => Some[Int]
       val h = f >=> g
                 ^

Почему не компилируется? Как сочинять f а также g с >=>?

1 ответ

Решение

Здесь есть две проблемы. Во-первых, предполагаемые типы ваших функций слишком специфичны. Option это монада, но Some не является. В таких языках, как Haskell эквивалент Some это даже не тип - это просто конструктор - но из-за того, как алгебраические типы данных кодируются в Scala, вы должны остерегаться этой проблемы. Есть два простых исправления - либо явно предоставьте более общий тип:

scala> val f: Int => Option[Int] = i => Some(i + 1)
f: Int => Option[Int] = <function1>

scala> val g: Int => Option[String] = i => Some(i.toString)
g: Int => Option[String] = <function1>

Или используйте Scalaz's handy some, который возвращает соответственно типизированный Some:

scala> val f = (i: Int) => some(i + 1)
f: Int => Option[Int] = <function1>

scala> val g = (i: Int) => some(i.toString)
g: Int => Option[String] = <function1>

Вторая проблема заключается в том, что >=> не предоставляется для простых старых монадических функций в Scalaz - вам нужно использовать Kleisli обертка:

scala> val h = Kleisli(f) >=> Kleisli(g)
h: scalaz.Kleisli[Option,Int,String] = Kleisli(<function1>)

Это именно то, что вы хотите - просто используйте h.run развернуть.

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