我正在尝试找到一种使用 foldl 执行以下功能的方法:
count a = length (filter (\i -> i) a)
它只计算布尔值列表中为真的值的数量。我自己尝试过
count = foldl (\i ->
case i of
True -> (1+)
False -> (0+)
) 0
这甚至没有编译。有什么建议么?
我正在尝试找到一种使用 foldl 执行以下功能的方法:
count a = length (filter (\i -> i) a)
它只计算布尔值列表中为真的值的数量。我自己尝试过
count = foldl (\i ->
case i of
True -> (1+)
False -> (0+)
) 0
这甚至没有编译。有什么建议么?
那么让我们来看看所涉及的函数的类型
Prelude> :t (\i -> case i of { True -> (1+) ; False -> (0+) })
(\i -> case i of { True -> (1+) ; False -> (0+) }) :: (Num t) => Bool -> t -> t
Prelude> :t foldl
foldl :: (a -> b -> a) -> a -> [b] -> a
因此,对于您的Bool
s 列表,b 是 Bool,但您使用的函数Bool
作为第一个参数,而不是第二个参数。累加值是第一个参数。所以你可以这样做
foldl (\acc p -> case p of { True -> acc + 1 ; False -> acc }) 0
或者,如果您只想修复参数顺序,请使用您的原始函数flip
Prelude> :t flip
flip :: (a -> b -> c) -> b -> a -> c
foldl (flip (\i -> case i of
True -> (1+)
False -> (0+)
)) 0
或者你可以更简洁:foldl (flip ((+) . fromEnum)) 0
怎么样:
count = foldl (\i v -> if v then i + 1 else i) 0
另一种没有的方法foldl
:
count list = sum $ map fromEnum list
归功于 Logan 的指出fromEnum
。以前没听说过那个。