斯卡拉的Monad特质

Dar*_*rio 24 generics functional-programming scala

(如何)以通用方式表示Scala中的monad(如MonadHaskell中的类型类)?是否有可能trait Monad为此目的定义一个?

Dan*_*wak 43

你可以尝试这样的事情:

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
}
Run Code Online (Sandbox Code Playgroud)

你当然会为你心中想要的任何其他monad定义类似的隐含对象.在Haskell术语中,您可以将MonadMonadicOption视为类型类和该类型类的特定实例.在monadicSyntax隐式转换只是演示了如何这种类型类可用于允许使用Scala的的for任何东西满足-comprehensions Monad类型类.

一般来说,Scala标准库中实现的大多数东西flatMap都是monad.Scala没有定义泛型Monad类型类(尽管这非常有用).相反,它依赖于解析器的语法技巧,允许将for-comprehensions与任何实现适当方法的东西一起使用.具体而言,这些方法是map,flatMapfilter(或foreachfilter用于势在必行形式).

  • 你实际上并没有真正使用它,是吗?:-)说真的,我已经和Scala一起工作了一段时间,而且我发现Haskell使用Monad类型类的很多情况都不会因为特征和子类型而出现在Scala中.上面给出的类型类虽然很酷,但肯定不是解决Scala问题的惯用方法. (4认同)
  • 有可能的是,我只是没有仔细观察它们出现的情况.或者,我可能正在设计我的代码,以便其他解决方案更好地工作.Scala允许对象功能解决方案解决在Haskell或ML等语言中需要大量功能魔法的问题(例如使用开放递归而不是函数技巧). (3认同)

and*_*dri 15

您可能会发现scalaz项目很有趣; 除了monad的实现之外,它还有许多其他(功能)东西.