我想在Scala中实现我自己的for-comprehension兼容的monad和functor.
我们以两个愚蠢的monad为例.一个monad是一个状态monad,包含一个可以映射或平面映射的"Int".
val maybe = IntMonad(5)
maybe flatMap( a => 3 * ( a map ( () => 2 * a ) ) )
// returns IntMonad(30)
Run Code Online (Sandbox Code Playgroud)
另一个monad采取像这样的功能组成......
val func = FunctionMonad( () => println("foo") )
val fooBar = func map ( () => println("bar") )
fooBar()
// foo
// bar
// returns Unit
Run Code Online (Sandbox Code Playgroud)
这个例子可能有一些错误,但你明白了.
我希望能够在Scala中使用这两种不同类型的Monad组成的for-understanding.像这样:
val myMonad = IntMonad(5)
for {
a <- myMonad
b <- a*2
c <- IntMonad(b*2)
} yield c
// returns IntMonad(20)
Run Code Online (Sandbox Code Playgroud)
我不是斯卡拉大师,但你明白了
我使用泛型函数合并了scala Set的scalaMap
def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] =
(Map[A, B]() /: (for (m <- ms; kv <- m) yield kv))
{
(a, kv) =>
a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv)
}
Run Code Online (Sandbox Code Playgroud)
这可以处理存在相同键冲突的情况.但是,我想在Scala Code中使用Java集合.我研究了一下然后发现了JavaConversions.我导入了它并写了这个
def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] =
(new util.HashMap[A, B] /: (for (m <- ms; kv <- m) yield kv))
{
case (a, kv) =>
a + (if …Run Code Online (Sandbox Code Playgroud)