对列表不太直接的monad绑定操作

时间:2016-03-03 06:55:18

标签: scala scalaz

我发现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中提取值,我该怎么办?如何使理解过程直观

1 个答案:

答案 0 :(得分:3)

OptionMaybe背后的直觉实际上与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实现类型都是唯一的。

您可能更愿意将其视为多个抽象级别(从更一般到更少):

  1. Monad具有绑定操作,将两个monadic值合并为一个:fold

  2. (>>=) :: m a -> (a -> m b) -> m b作为monad实例使用以下内容实现bind:List - 将函数映射到所有元素并将结果连接到单个列表中。

  3. 您可以根据需要为绑定功能提供函数xs >>= f = concat (map f xs)的实现(客户端 - >订单示例)。

  4. 一旦你知道了monad实例(fList)的绑定行为,你可以考虑使用它并且"忘记"关于实际实施。