我正在学习Haskell并尝试创建一个retainTrue函数,它接受一个元素列表和一个布尔列表,然后返回一个与真正的布尔值相对应的元素列表。所以retainTrue :: [a] -> [Bool] -> [a]
示例测试retainTrue [1, 2, 3] [True, False, True]
将返回[1, 3]
。
我通常会为此目的使用过滤器,但添加布尔列表会让我失望。谁能推荐一种优雅的方法来解决这个问题?
答案 0 :(得分:4)
这是一种不使用zip
的方法,尽管它本质上使用相同的概念:
retainTrue :: [a] -> [Bool] -> [a]
retainTrue [] _ = []
retainTrue _ [] = []
retainTrue (x:xs) (y:ys) = if y then x : f xs ys else f xs ys
然而,有一点需要注意 - 列表需要具有相同的长度。
这可以更简洁地写成
retainTrue (x:xs) (y:ys) = [x|y] ++ f xs ys
当然,您仍需要保留空列表模式检查。
答案 1 :(得分:2)
评论中提到的zip
解决方案是:
retainTrue :: [a] -> [Bool] -> [a]
retainTrue xs bs = map fst $ filter snd $ zip xs bs
我们的想法是首先从[Bool]
注入额外信息,然后根据额外信息注入filter
,然后删除额外信息(map fst
)。