什么是scalaz filterM方法?

时间:2016-09-12 18:35:57

标签: scala scalaz

这个scalaz tutorial提供了使用filterM方法的示例,但它没有解释它。

List(1, 2, 3) filterM { x => List(true, false) }
res19: List[List[Int]] = List(List(1, 2, 3), List(1, 2), List(1, 3), List(1), List(2, 3), List(2), List(3), List())

我看到我可以传递任何大小的布尔列表。这个filterM方法是什么?

另外,是否有一本关于scalaz的书/教程有更多解释?

3 个答案:

答案 0 :(得分:1)

根据实施,您需要传递函数A => F[Boolean],例如F: ApplicativefilterM遍历列表,过滤了传递谓词的元素(返回F[true]),最后将此List放入F

一个更简单的例子:

List(1, 2, 3).filterM[Option](_.some.map(_ % 2 == 0)) // Some(List(2))

请注意,这不仅可以考虑truefalse,还可以None,从而为您提供额外的自由度。您可以尝试不同的应用程序来掌握这个概念。

在您输入的示例中,List也是Applicative。那么,会发生什么(因为它是递归的,更容易从最后开始):
1)当你在列表的末尾时 - 你只得到一个空列表
2)你有一个列表3 :: Nil。将谓词应用于3会为您提供List(true, false)。所以,你正在考虑整个List(3)和尾部List() 3)接下来是22 -> true :: false映射到head :: head :: tail List(2) :: List(2, 3)。将其添加到您之前的内容中,您将获得List(List(2, 3), List(2), List(3), List())
4)现在是最后一步,你得到一个。将1添加到true的每个列表中的方式与false的其余列表相同。

List(List(1, 2, 3), List(1, 2), List(1, 3), List(1), List(2, 3), List(2), List(3), List())

我添加了一些日志记录,以明确发生的情况:

current list: List(1, 2, 3)
current list: List(2, 3)
current list: List(3)
current list: List()
filtered value: List(List())
taking head and tail :   List(3)
taking tail: List()
filtered value: List(List(3), List())
taking head and tail :   List(2, 3)
taking head and tail :   List(2)
taking tail: List(3)
taking tail: List()
filtered value: List(List(2, 3), List(2), List(3), List())
taking head and tail :   List(1, 2, 3)
taking head and tail :   List(1, 2)
taking head and tail :   List(1, 3)
taking head and tail :   List(1)
taking tail: List(2, 3)
taking tail: List(2)
taking tail: List(3)
taking tail: List()
List(List(1, 2, 3), List(1, 2), List(1, 3), List(1), List(2, 3), List(2), List(3), List())

答案 1 :(得分:0)

我不完全确定最新情况,但结果只是一个真值表。似乎filterM只合并了两个applicatives,其中一个是applicative of Boolean,因此基本上结果是对true的每个组合的应用。

1,2,3   (true, true ,true)
1,2     (true, true, false)
2,3     (false, true, true)
1,3     (true, false, true)
1       (true, false, false)
2       (false, true, false)
3       (false, false, true)
()      (false, false, false)

答案 2 :(得分:0)

这是一个非常古老的问题。我会回答以防万一其他人在想。

你可以从Learn You a Haskell for Good!找到一个很好的解释。在我引用的链接中搜索filterM。

在书中,它说明了以下内容(你可以看出haskell语法):

  

过滤功能几乎是Haskell编程的一部分(地图是黄油)。它需要一个谓词和一个列表来过滤掉然后返回一个新列表,其中只保留满足谓词的元素。它的类型是:

     

filter ::(a - > Bool) - > [a] - > [a]

     

谓词采用列表的元素并返回Bool值。现在,如果它返回的Bool值实际上是monadic值怎么办?哇!也就是说,如果它带有上下文怎么办?这可行吗?例如,如果谓词产生的每个True或False值都具有伴随的monoid值,如[“Accepted the number 5”]或[“3 is too small”],该怎么办?听起来它可以工作。如果是这种情况,我们希望结果列表还附带一路上记录的所有日志值。因此,如果谓词返回的Bool带有上下文,我们期望最终结果列表也附加一些上下文,否则每个Bool附带的上下文将丢失。

     

filterM ::(Monad m)=> (a - > m Bool) - > [a] - > m [a]

     

谓词返回一个monadic值,其结果是Bool,但由于它是一个monadic值,它的上下文可以是从可能的失败到非确定性等等!为了确保上下文反映在最终结果中,结果也是一个monadic值。

至于一本好书供参考,我会阅读以下Scalaz的简要教程:Learning Scalaz。如果你需要进一步深入解释,我会回到学习你的哈克尔书。

对于我来说,对于Scalaz示例中的filterM做什么仍然没有意义。根据Haskell书中的解释,它完全有道理。

编辑:明确了什么没有意义。