什么是 scalaz filterM 方法?
what is the scalaz filterM method?
这个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 方法是什么?
此外,是否有 book/tutorial scalaz 的更多解释?
根据实现,需要传递函数A => F[Boolean]
,比如F: Applicative
。
filterM
遍历列表,过滤元素,为其传递谓词(返回 F[true]
),最后将此 List
放入 F
.
更简单一点的例子:
List(1, 2, 3).filterM[Option](_.some.map(_ % 2 == 0)) // Some(List(2))
请注意,这为您提供了额外的自由度,不仅可以考虑 true
或 false
,还可以考虑 None
。你可以尝试不同的Applicatives来掌握这个概念。
在您输入的示例中,List
也是 Applicative。那么,会发生什么(因为它是递归的,所以从最后开始更容易):
1) 当你在列表的末尾时 - 你只会得到一个空列表
2) 你有一个列表 3 :: Nil
。将谓词应用于 3
会得到 List(true, false)
。因此,您正在使用整个 List(3)
和尾部 List()
.
3) 接下来是 2
。 2 -> 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())
我不完全确定发生了什么,但结果是事实 table。似乎 filterM
只是组合了两个 applicatives
,其中一个是 applicative of Boolean
所以基本上结果是对导致 true
.[=15= 的每个组合的应用]
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)
这是一个很老的问题。我只是回答以防万一其他人想知道。
你可以从Learn You a Haskell for Good!中找到一个很好的解释。在我引用的 link 中搜索 filterM。
在书中,它说了以下内容(你可以辨认出 haskell 语法):
The filter function is pretty much the bread of Haskell programming (map being the butter). 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]
The predicate takes an element of the list and returns a Bool value. Now, what if the Bool value that it returned was actually a monadic value? 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"]? 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.
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! To ensure that the context is reflected in the final result, the result is also a monadic value.
作为参考的好书,我会阅读以下Scalaz作为简要教程:Learning Scalaz。如果您需要更深入的解释,我会回去给您学习一本 haskell 书。
我仍然不明白 filterM 在 Scalaz 示例中的作用。从 Haskell 书中的解释来看,这是完全有道理的。
编辑:澄清了不合理之处。
这个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 方法是什么?
此外,是否有 book/tutorial scalaz 的更多解释?
根据实现,需要传递函数A => F[Boolean]
,比如F: Applicative
。
filterM
遍历列表,过滤元素,为其传递谓词(返回 F[true]
),最后将此 List
放入 F
.
更简单一点的例子:
List(1, 2, 3).filterM[Option](_.some.map(_ % 2 == 0)) // Some(List(2))
请注意,这为您提供了额外的自由度,不仅可以考虑 true
或 false
,还可以考虑 None
。你可以尝试不同的Applicatives来掌握这个概念。
在您输入的示例中,List
也是 Applicative。那么,会发生什么(因为它是递归的,所以从最后开始更容易):
1) 当你在列表的末尾时 - 你只会得到一个空列表
2) 你有一个列表 3 :: Nil
。将谓词应用于 3
会得到 List(true, false)
。因此,您正在使用整个 List(3)
和尾部 List()
.
3) 接下来是 2
。 2 -> 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())
我不完全确定发生了什么,但结果是事实 table。似乎 filterM
只是组合了两个 applicatives
,其中一个是 applicative of Boolean
所以基本上结果是对导致 true
.[=15= 的每个组合的应用]
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)
这是一个很老的问题。我只是回答以防万一其他人想知道。
你可以从Learn You a Haskell for Good!中找到一个很好的解释。在我引用的 link 中搜索 filterM。
在书中,它说了以下内容(你可以辨认出 haskell 语法):
The filter function is pretty much the bread of Haskell programming (map being the butter). 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]
The predicate takes an element of the list and returns a Bool value. Now, what if the Bool value that it returned was actually a monadic value? 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"]? 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.
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! To ensure that the context is reflected in the final result, the result is also a monadic value.
作为参考的好书,我会阅读以下Scalaz作为简要教程:Learning Scalaz。如果您需要更深入的解释,我会回去给您学习一本 haskell 书。
我仍然不明白 filterM 在 Scalaz 示例中的作用。从 Haskell 书中的解释来看,这是完全有道理的。
编辑:澄清了不合理之处。