scala - 将 monad 组合成元组运算符 scalaz

标签 scala functional-programming monads scalaz

因此,Scala 中一个非常常见的模式是 for 理解,如下所示:

for {
  i <- monadA
  j <- monadB
} yield (i, j)

对于 3 元组、...、n 元组也是如此。这在我的代码中变得如此普遍,我想象 scalaz 提供了一些很棒的运算符来为我做到这一点,例如monadAunnyOperatormonadBfunnyOperatormonadC。我环顾四周,似乎找不到任何东西。因此,我为 2 元组和 3 元组定义了自己的隐式类,但更喜欢使用 scalaz。

奖金

作为当前接受的答案,很高兴看到有人告诉如何进行编译:

import scalaz.Scalaz._

// Like a 1 element list
case class MyMonad[+T](x: T) {
  def map[U](f: T => U): MyMonad[U] = MyMonad(f(x))
  def flatMap[U](f: T => MyMonad[U]): MyMonad[U] = f(x)
}

val myMonad: MyMonad[(Int, Int)] = (MyMonad(1) |@| MyMonad(2)).tupled

并且不给出:

error: value |@| is not a member of MyMonad[Int]

额外解决方案:

您需要“提供一个应用实例”,例如

implicit def myMonadApplicative: Bind[MyMonad] = new Bind[MyMonad] {
  def bind[A, B](fa: MyMonad[A])(f: A => MyMonad[B]): MyMonad[B] = fa.flatMap(f)
  def map[A, B](fa: MyMonad[A])(f: A => B): MyMonad[B] = fa.map(f)
}

最佳答案

鉴于每个 Monad 都是一个 Applicative,您也可以使用

(monadA |@| monadB).tupled

例如

scala> val b: List[(Int, Int)] = (List(1, 2, 3) |@| List(4, 6)).tupled
b: List[(Int, Int)] = List((1,4), (1,6), (2,4), (2,6), (3,4), (3,6))

关于scala - 将 monad 组合成元组运算符 scalaz,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27943957/

相关文章:

javascript - 有人可以在这个 "function factory"中解释 x 和 y 吗?

list - 如何在列表和 ListT monad 转换器之间干净地转换?

scala - 在测试中设置 javaOptions for Play/SBT

javascript - 包装函数帮助器

json - Scalaz 树到 JSON

java - 如何在 List(不是 List)的 Function<T, R> 参数中应用

scala - 与 FlatMap/Map 转换的 for 理解相混淆

haskell - 伴随仿函数决定了单子(monad)更改器(mutator),但是升力在哪里呢?

scala - 如何让 SBT 并行运行测试套件?

scala - 在 Scala 中并发处理