如何使用splitWhen函数和谓词函数将列表拆分为haskell中的两个奇数和偶数列表

时间:2014-12-30 23:23:47

标签: haskell functional-programming

我是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])

如果上述方法有误,请提出其他解决此问题的方法。但我也遇到了同样的问题。

提前致谢

2 个答案:

答案 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])

这解决了我的问题,虽然它不像我在问题中提到的那样