也许我不理解一些基本原理,但一般来说flatMap
的签名是什么?我们想象一下,我想实现支持T
表达式的for
类型,然后我需要map
实现flatmap
,withFilter
和T
。有没有这样的界面?
更确切地说,签名的来源是什么:
class T[+A] {
def flatMap[B](f: (A) => T[B]): T[B]
}
或者它是一个定义?我可以用不同的签名实现flatmap
吗?
答案 0 :(得分:6)
一般来说,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]
对于Seq:
def flatMap[B](f: (A) ⇒ Seq[B]): Seq[B]
当然,在scala API中,您会看到Seq,List的其他签名 - 因为所有集合的特征TraversableLike
都有通用签名。
对于monad函数map应该:
m map f == m flatMap (x => unit(f(x)))
单位unit(x) = single(x)
,例如:
<强>更新强> 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
答案 1 :(得分: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方法的单一方法。