(Как) можно ли представить монады в Scala общим образом (например, Monad
typeclass в Haskell)? Можно ли как-то определить trait Monad
для этой цели?
Монада в Scala
Ответ 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 проект; у него есть много других (функциональных) вещей, а также реализация монад.
Ответ 3
Посмотрите http://www.scala-lang.org/api/current/index.html#scala.collection.generic.FilterMonadic. Класс case уже встроен в язык и широко используется для коллекций...
Ответ 4
http://www.codecommit.com/blog/ruby/monads-are-not-metaphors
Здесь полезная и довольно длинная статья о шаблоне Монады и ее реализация в Scala Даниила, который написал принятый ответ на этот вопрос.
(Для тех, кто наткнется на этот "древний" вопрос через мистические способы поиска сайта StackOverflow.)
Ответ 5
Scala обеспечивает аналогичную способность к классам типа Haskell с использованием неявных параметров, в частности границ представления и границ контекста. Вы можете видеть такие вещи в использовании, особенно на Scala 2.8, с такими чертами, как Ordering
и Numeric
.
Тем не менее, посмотрите проект Scalaz. У этого есть монады, функторы, стрелки... весь shebang.