在Scala中重新创建Haskell的`replicateM`的行为

时间:2014-10-29 17:32:06

标签: scala monads traits

我正在尝试学习如何在Scala中执行monadic代码,但我错过了Haskell将类型约束为类型的能力,从而声明了函数的类型。

例如,我正在尝试在Scala中从replicateM编写类似Control.Monad的内容。如果不关心类型注释,这将是:

def replicateM(n: Int)(x: M[A]): M[List[A]] = n match {
  case 0 => map(x => List())
  case _ => for {
    head <- x
    tail <- replicateM(n-1)(x)
  } yield head: tail
}

(我发现这可能不是更有效的实现,它只是一种简单的编写方式)。

我绊倒的地方是:我如何正确注释这里的类型? M是什么类型的?如何仅将M限制为对其定义flatMap的类型?我觉得我可以用特质做到这一点,但我不确定如何。

1 个答案:

答案 0 :(得分:6)

我认为如果您在Scala中寻找Haskell,您肯定需要查看scalaz。它已经有replicateM,Monads,Monoids,Monad Transformers等等。

  import scalaz._
  import Scalaz._

  println(Option(1).replicateM(10))

结果

Some(List(1, 1, 1, 1, 1, 1, 1, 1, 1, 1))