我是Haskell的新手,我想根据以下条件拆分列表:如果使用splitWhen函数将list的元素作为偶数或奇数,则将第一个参数作为布尔条件。这个布尔条件是另一个名为checkEven的函数的返回。但是如何将元素传递给checkEven函数。这甚至可能吗?
checkEven n=(n mod 2==0)
splitList x= splitWhen (checkEven(<???>)) x
main =do
print (splitList [0,1,2,3,-1])
如果上述方法有误,请提出其他解决此问题的方法。但我也遇到了同样的问题。
提前致谢
答案 0 :(得分:4)
不,splitWhen
无法为您执行此操作,因为它会丢弃分隔符,并且您需要保留所有输入数据:
splitWhen checkEven [1,2,3,4,6,8,9,10] == [[1],[3],[],[],[9],[]]
您可以使用Data.List.Split库来实现这一点,因为它非常灵活。
只要元素是偶数,我们就可以分割,所以我们使用whenElt even
:
ghci> :m Data.List.Split
ghci> split (whenElt even) [1,11,2,22,3,33,333,4,6,8,9,99,999,10,100]
[[1,11],[2],[],[22],[3,33,333],[4],[],[6],[],[8],[9,99,999],[10],[],[100],[]]
但是我们希望将多个分隔符(例如2,22
)压缩到一个列表中,而不是像我们那样在其间有一个奇数的空列表,所以我们使用condense
修饰符:
ghci> split (condense $ whenElt even) [1,11,2,22,3,33,333,4,6,8,9,99,999,10,100]
[[1,11],[2,22],[3,33,333],[4,6,8],[9,99,999],[10,100],[]]
但是让我们删除最后发生的空白列表,因为最后还有另一个空的赔率列表:
ghci> split (dropFinalBlank . condense $ whenElt even) [1,11,2,22,3,33,333,4,6,8,9,99,999,10,100]
[[1,11],[2,22],[3,33,333],[4,6,8],[9,99,999],[10,100]]
另一方面,如果您是从头开始实施此功能,那么您需要使用break
功能。
答案 1 :(得分:0)
感谢@AndrewC的回答。我很困惑如何拆分列表并尝试使用内置的 splitWhen 函数。但实际上我找到了不使用 splitWhen 函数但使用prelude函数的解决方案。
splitOE::[Integer]->(Integer->Bool)->([Integer],[Integer])
nums=[1,3,5,2,6,7,12,14,9]
splitOE xs preFunc=(a,b)
where a=[x|x<-xs,preFunc x]
b=[x|x<-xs,(not.preFunc) x]
main = do
print (splitOE nums even)
*Main> main
([2,6,12,14],[1,3,5,7,9])
这解决了我的问题,虽然它不像我在问题中提到的那样