我刚开始学习Haskell,并且开始研究理解理解,这使我可以通过为更大的集合提供条件来形成子集。
我试图做出一个理解,该理解采用一个嵌套列表(包含其他整数列表),并从中删除所有正奇数和空的内部列表。
testList= [-3]:[-5,8]:[[1,3,5,7,9],[],[4,6,8,10],[1,3,6,7,9],[],[1]]
removingOnlyPosOdds xxs = [ [x | x <-xs, not (odd x && x > 0 )] | xs <- xxs, [] /= xs ]
testList
应用于其上的理解功能之前,如下所示:
[[-3],[-5,8],[1,3,5,7,9],[],[4,6,8,10],[1,3,6,7,9],[],[1]]
应用removingOnlyPosOdds
testList后
The outcome was
[[-3],[-5,8],[],[4,6,8,10],[6],[]]
所以我意识到函数描述中的"[] /= xs"
正在删除已经存在的
"[]"
中的 testList
内部列表;但不是由我从内部列表中删除正奇数引起的新的形成。
为了在代码方面也删除这些代码,下一步应该做什么?
我希望它看起来像
[[-3],[-5,8],[4,6,8,10],[6]]
是否有一种方法可以一概而论地概括理解能力?
或者还有另一种方法可以更好地处理事物的清除(例如,空的内部列表)并创建更指定的集合?
答案 0 :(得分:3)
您可以添加一些额外的过滤器,并使用let
子句防止两次进行相同的列表理解,例如:
removingOnlyPosOdds xxs = [ ys | xs <- xxs, let ys = [x | x <-xs, not (odd x && x > 0 )], not (null ys) ]
或者我们可以添加一些额外的过滤条件,例如:
removingOnlyPosOdds :: Integral i => [[i]] -> [[i]]
removingOnlyPosOdds = filter (not . null) . map (filter (\x -> not (odd x && x > 0)))
或什至没有积分:
import Control.Monad(liftM2)
removingOnlyPosOdds :: Integral i => [[i]] -> [[i]]
removingOnlyPosOdds = filter (not . null) . map (filter (not . liftM2 (&&) odd (>0)))
例如:
Prelude> removingOnlyPosOdds [[-3],[-5,8],[1,3,5,7,9],[],[4,6,8,10],[1,3,6,7,9],[],[1]]
[[-3],[-5,8],[4,6,8,10],[6]]