我发现Option
Monad直观易懂,而List
则不然。
Some(1) >>= { x=>Some(x+1)}
Ma -> a -> Mb -> Mb
如果我从Some(1)中提取值,我知道它是1
但在列表案例中
List(3,4,5) flatMap { x=> List(x,-x) }
如果我从List中提取值,我该怎么办?如何使理解过程直观
答案 0 :(得分:3)
Option
或Maybe
背后的直觉实际上与List
monad非常相似。主要区别在于List
是非确定性的 - 我们不知道我们可以获得多少值,当Option
时,它总是一个成功,零就失败。空列表被视为失败。
我认为piece很好地描述了它:
对于列表,monadic绑定涉及将一组连接在一起 计算列表中的每个值。与列表一起使用时, >> =的签名变为:
(>> =):: [a] - > (a - > [b]) - > [b]
即,给出一个列表以及将a映射到列表的函数 对于b,绑定将此函数应用于输入中的每个a 并将所有生成的b连接成一个列表。
example列表实现:
instance Monad [] where
return x = [x]
xs >>= f = concat (map f xs)
fail _ = []
很抱歉将Haskell放入Scala答案中,但这是我用来理解这些内容的资源。
Scala的flatMap
并不完全是Haskell的绑定>>=
,但非常接近它。这一切意味着什么?:
想象一下您有一个客户列表List[Client]
的实际情况,您可以将它们绑定到单个订单列表List[Order]
,这些订单将flatMap
或{自动为您展平{1}}。如果您改用>>=
,则会获得map
。在实践中,您将提供List[List[Order]]
使用的功能,类似于您向>>=
提供功能的方式 - 您决定如何生成/聚合数据等。 bind的作用是为两个monadic值提供一个通用模式,并且每个monad实现类型都是唯一的。
您可能更愿意将其视为多个抽象级别(从更一般到更少):
Monad具有绑定操作,将两个monadic值合并为一个:fold
。
(>>=) :: m a -> (a -> m b) -> m b
作为monad实例使用以下内容实现bind:List
- 将函数映射到所有元素并将结果连接到单个列表中。
您可以根据需要为绑定功能提供函数xs >>= f = concat (map f xs)
的实现(客户端 - >订单示例)。
一旦你知道了monad实例(f
,List
)的绑定行为,你可以考虑使用它并且"忘记"关于实际实施。