函数的filter类接受一个条件( ->布尔值),并在过滤时应用它。
当您有多个条件时,使用筛选器的最佳方式是什么?
我使用了应用函数liftA2而不是liftM2,因为出于某种原因,我不明白liftM2在纯代码中是如何工作的。
发布于 2009-05-08 13:38:48
liftM2组合器可以用在阅读器monad中,以一种“更实用”的方式来完成这项工作:
import Control.Monad
import Control.Monad.Reader
-- ....
filter (liftM2 (&&) odd (> 100)) [1..200]
请注意,导入非常重要;Control.Monad.Reader提供了Monad (e ->)实例来实现这一切。
这样做的原因是读取器monad对于某些环境e只是(e ->)。因此,布尔谓词是一个0元一元函数,在与其参数相对应的环境中返回bool。然后,我们可以使用liftM2将环境分布到两个这样的谓词上。
或者,简而言之,当类型工作时,liftM2的行为有点像这样:
liftM2 f g h a = f (g a) (h a)
如果您希望能够轻松地链接这些组件,并且/或者不想与liftM2打交道,也可以定义一个新的组合器:
(.&&.) :: (a -> Bool) -> (a -> Bool) -> (a -> Bool)
(.&&.) f g a = (f a) && (g a)
-- or, in points-free style:
(.&&.) = liftM2 (&&)
filter (odd .&&. (> 5) .&&. (< 20)) [1..100]
发布于 2009-05-08 13:28:03
嗯,你可以在Haskell中随心所欲地组合函数(只要类型是正确的),并使用lambdas,你甚至不必命名谓词函数,即,
filter (\x -> odd x && x > 100) [1..200]
发布于 2009-05-08 13:40:14
假设您的条件存储在一个名为conditions
的列表中。此列表的类型为[a -> Bool]
。
要将所有条件应用于值x
,可以使用map
map ($ x) conditions
这会将每个条件应用于x
,并返回一个Bool列表。要将此列表缩减为单个布尔值,如果所有元素都为True,则为True,否则为False,可以使用and
函数:
and $ map ($ x) conditions
现在您有了一个组合了所有条件的函数。让我们给它起个名字:
combined_condition x = and $ map ($ x) conditions
此函数的类型为a -> Bool
,因此我们可以在调用filter
时使用它
filter combined_condition [1..10]
https://stackoverflow.com/questions/841851
复制相似问题