Подтвердить что ты не робот

Монада в Scala

(Как) можно ли представить монады в Scala общим образом (например, Monad typeclass в Haskell)? Можно ли как-то определить trait Monad для этой цели?

4b9b3361

Ответ 1

Вы можете попробовать что-то вроде этого:

trait Monad[+M[_]] {
  def unit[A](a: A): M[A]
  def bind[A, B](m: M[A])(f: A => M[B]): M[B]
}

// probably only works in Scala 2.8
implicit def monadicSyntax[M[_], A](m: M[A])(implicit tc: Monad[M]) = new {
  private val bind = tc.bind(m) _

  def map[B](f: A => B) = bind(f compose tc.unit)

  def flatMap[B](f: A => M[B]) = bind(f)
}

implicit object MonadicOption extends Monad[Option] {
  def unit[A](a: A) = Some(a)

  def bind[A, B](opt: Option[A])(f: A => Option[B]) = opt flatMap f
}

Вы, конечно, определите похожие неявные объекты для любой другой монады, которую желает ваше сердце. В терминах Haskell вы можете думать о Monad как typeclass и MonadicOption как о конкретном экземпляре этого типа. Неявное преобразование monadicSyntax просто демонстрирует, как этот класс может использоваться, чтобы позволить использовать Scala for -понимание с чем-либо, что удовлетворяет классу Monad.

Вообще говоря, большинство вещей в стандартной библиотеке Scala, которые реализуют flatMap, являются монадами. Scala не определяет общий тип Monad typeclass (хотя это было бы очень полезно). Вместо этого он опирается на синтаксический трюк анализатора, позволяющий использовать for -понимание с чем-либо, что реализует соответствующие методы. В частности, эти методы map, flatMap и filter (или foreach и filter для императивной формы).

Ответ 2

Вы можете найти интересный scalaz проект; у него есть много других (функциональных) вещей, а также реализация монад.

Ответ 4

http://www.codecommit.com/blog/ruby/monads-are-not-metaphors

Здесь полезная и довольно длинная статья о шаблоне Монады и ее реализация в Scala Даниила, который написал принятый ответ на этот вопрос.

(Для тех, кто наткнется на этот "древний" вопрос через мистические способы поиска сайта StackOverflow.)

Ответ 5

Scala обеспечивает аналогичную способность к классам типа Haskell с использованием неявных параметров, в частности границ представления и границ контекста. Вы можете видеть такие вещи в использовании, особенно на Scala 2.8, с такими чертами, как Ordering и Numeric.

Тем не менее, посмотрите проект Scalaz. У этого есть монады, функторы, стрелки... весь shebang.