4

也许我不了解一些基础知识,但是flatMap一般的签名是什么?假设我想实现类型支持T表达式for,然后我需要mapflatmap并由. 有没有类似的接口?withFilterT

更准确地说,签名的来源是什么:

class T[+A] {

    def flatMap[B](f: (A) => T[B]): T[B]

}

或者它是一个定义?我flatmap可以用不同的签名实现吗?

4

2 回答 2

7

一般来说 flatMap 有签名:

class T[+A] {

def flatMap[B](f: (A) ⇒ T[B]): T[B]
def map[B](f: (A) ⇒ B): T[B]

}

例如对于选项:

def flatMap[B](f: (A) ⇒ Option[B]): Option[B]

对于序列:

def flatMap[B](f: (A) ⇒ Seq[B]): Seq[B]

当然,在 scala API 中,您会看到 Seq、List 的其他签名——因为TraversableLike所有集合的 trait 中都有通用签名。

对于 monad 函数映射应该:

m map f == m flatMap (x => unit(f(x)))

其中单位unit(x) = single(x),例如:

  • List 是一个带有 unit(x) = List(x) 的 monad
  • Set 是具有 unit(x) = Set(x) 的单子
  • Option 是一个带有 unit(x) = Some(x) 的 monad

更新 flatMap/map 没有接口。查看示例(复制到您的 REPL):

class C[+A](val a:A) { 
 def flatMap[B](f:(A) => C[B]):C[B] = f(a)
 def map[B](f:(A)=>B):B = f(a)
}

然后在 REPL 中调用方法:

scala> for { k<- new C(3)} yield {k}
res2: Int = 3
于 2013-11-08T08:14:24.373 回答
1

无需特殊接口。但如果是这样,您可以实现FilterMonadic[+A, +Repr]通用接口。

更新

SLS - 6.19 用于理解和循环。

方法:map、withFilter、flatMap 和 foreach - 可以针对不同的运营商类型以不同的方式实现。代码:

class A {
  def map(f: Int => Boolean): Boolean = f(10)
  def flatMap(f: Int => Boolean): Boolean = f(20)
}

for(x <- new A; y <- new A) yield x == y

class T[+A] {
  def flatMap[B](f: (A) ⇒ T[B]): T[B]
}

不是定义 flatMap 方法的单一方法。

于 2013-11-08T08:19:47.707 回答