简体   繁体   English

什么是scalaz filterM方法?

[英]what is the scalaz filterM method?

this scalaz tutorial provides an example of using the filterM method, but it does not explain it. 这个scalaz教程提供了一个使用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())

I see that I can pass it a boolean list of any size. 我看到我可以传递一个任何大小的布尔列表。 what is this filterM method? 这个filterM方法是什么?

also, is there a book/tutorial of scalaz with a bit more explanations? 还有,还有一本关于scalaz的书/教程,还有一些解释吗?

According to implementation, you need to pass the function A => F[Boolean] , such as F: Applicative . 根据实现,您需要传递函数A => F[Boolean] ,例如F: Applicative filterM goes over list, filters elements, for which predicate passed ( returned F[true] ), and in the end put this List into F . filterM遍历列表,过滤元素,谓词传递(返回F[true] ),最后将此List放入F

A bit simpler example: 一个简单的例子:

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

Note, that this gives you additional degree of freedom, to not only consider true or false , but as well None . 请注意,这为您提供了额外的自由度,不仅要考虑truefalse ,还要考虑None You may try it for different Applicatives to grasp the concept. 您可以尝试不同的应用程序来掌握这个概念。

In the example you put in, the List is the Applicative as well. 在您输入的示例中, List也是Applicative。 So that, what happens (because it is recursive, it easier to go from the end): 那么,会发生什么(因为它是递归的,更容易从最后开始):
1) when you are at the end of the list - you just get an empty list 1)当你在列表的末尾 - 你只是得到一个空列表
2) you have a list 3 :: Nil . 2)你有一个清单3 :: Nil Applying a predicate to 3 gives you List(true, false) . 将谓词应用于3会给出List(true, false) So, you are taking the whole List(3) and the tail List() . 因此,您将获取整个List(3)和尾部List()
3) next comes 2 . 3)接下来2 2 -> true :: false which maps to head :: head :: tail which is List(2) :: List(2, 3) . 2 -> true :: false ,它映射到head :: head :: tail ,它是List(2) :: List(2, 3) Appending it to what you had before, you are getting List(List(2, 3), List(2), List(3), List()) 将它附加到您之前的内容,您将获得List(List(2, 3), List(2), List(3), List())
4) now comes the last step, where you get one. 4)现在是最后一步,你得到一个。 The same way you prepend 1 to each of the list for the true and take the rest for the false . 同样的方法是将1到每个列表中的true ,并将其余部分用于false

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

I added some logging, to make clear what happens: 我添加了一些日志记录,以明确发生的情况:

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())

I'm not entirely sure whats going on but the result is just a truth table. 我不完全确定最新情况,但结果只是一个真值表。 It seems like filterM just combines two applicatives , one of which is an applicative of Boolean so basically the result is an applicative for every combination that results in true . 似乎filterM只结合了两个applicatives ,其中一个是applicative of Booleanapplicative 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)

This is a pretty old question. 这是一个非常古老的问题。 I'll just answer just in case anyone else was wondering. 我会回答以防万一其他人在想。

You can find a pretty good explanation from Learn You a Haskell for Good! 你可以从Learn the a Haskell for Good中找到一个很好的解释 . Search for filterM in the link I referenced. 在我引用的链接中搜索filterM。

In the book, it says the following (you can kind of make out the haskell syntax): 在本书中,它说明了以下内容(您可以使用haskell语法):

The filter function is pretty much the bread of Haskell programming (map being the butter). 过滤器功能几乎是Haskell编程的一部分(地图是黄油)。 It takes a predicate and a list to filter out and then returns a new list where only the elements that satisfy the predicate are kept. 它需要一个谓词和一个列表来过滤掉然后返回一个新列表,其中只保留满足谓词的元素。 Its type is this: 它的类型是这样的:

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

The predicate takes an element of the list and returns a Bool value. 谓词采用列表的元素并返回Bool值。 Now, what if the Bool value that it returned was actually a monadic value? 现在,如果它返回的Bool值实际上是monadic值怎么办? Whoa! 哇! That is, what if it came with a context? 也就是说,如果它带有上下文怎么办? Could that work? 这可行吗? For instance, what if every True or a False value that the predicate produced also had an accompanying monoid value, like ["Accepted the number 5"] or ["3 is too small"]? 例如,如果谓词产生的每个True或False值都具有伴随的monoid值,如[“Accepted the number 5”]或[“3 is too small”],该怎么办? That sounds like it could work. 听起来它可以工作。 If that were the case, we'd expect the resulting list to also come with a log of all the log values that were produced along the way. 如果是这种情况,我们希望结果列表还附带一路上记录的所有日志值。 So if the Bool that the predicate returned came with a context, we'd expect the final resulting list to have some context attached as well, otherwise the context that each Bool came with would be lost. 因此,如果谓词返回的Bool带有上下文,我们期望最终结果列表也附加一些上下文,否则每个Bool附带的上下文将丢失。

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

The predicate returns a monadic value whose result is a Bool, but because it's a monadic value, its context can be anything from a possible failure to non-determinism and more! 谓词返回一个monadic值,其结果是Bool,但因为它是一个monadic值,它的上下文可以是从可能的失败到非确定性等等! To ensure that the context is reflected in the final result, the result is also a monadic value. 为确保上下文反映在最终结果中,结果也是一个monadic值。

As for a good book for reference, I would read the following Scalaz for a brief tutorial: Learning Scalaz . 至于一本好的参考书,我会阅读以下Scalaz的简要教程: 学习Scalaz If you need further in depth explanation, I would go back to the learn you a haskell book. 如果您需要进一步深入解释,我会回过头来学习一本哈克尔书。

Still doesn't make sense for me what filterM does in the Scalaz example. 对于我来说,对于Scalaz示例中的filterM做什么仍然没有意义。 From the explanation in the Haskell book it makes complete sense. 根据Haskell书中的解释,它完全有道理。

Edit: clarified what didn't make sense. 编辑:澄清什么没有意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM