Как использовать>=> в 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
развернуть.