0
votes

I am new to Haskell and I wanted to split a list based on the condition that if elements of list are even or odd using splitWhen function which takes first parameter as boolean condition. This boolean condition is the return of another function called checkEven. But how can I pass the element to checkEven function. Is this even possible ?

checkEven n=(n mod 2==0)
splitList x= splitWhen (checkEven(<???>)) x
main =do 
 print (splitList [0,1,2,3,-1])

Please suggest other ways to solve this problem if above method is wrong. but I was given the same problem.

Thanks in advance

2
What is splitWhen?jub0bs
@Jubobs it is the inbuilt function that works with list. I found it in hackage.haskell.org/package/split-0.1.1/docs/…rmsorPth
@Jubobs fpcomplete.com/hoogle?q=splitWhen&env=ghc-7.8-stable-14.09 FPComplete's hoogle searches more packages than haskellwiki's. splitWhen :: (a -> Bool) -> [a] -> [[a]] giving splitWhen (<0) [1,3,-4,5,7,-9,0,2] == [[1,3],[5,7],[0,2]] AndrewC
Are you looking for the partition function? (link). Otherwise I would familiarize myself with break and span(link) which are useful list parsing functions.ErikR

2 Answers

4
votes

No, splitWhen can't do that for you, because it throws away the delimeters, and you need to keep all the input data:

splitWhen checkEven [1,2,3,4,6,8,9,10] == [[1],[3],[],[],[9],[]]

You can use the Data.List.Split library to do that, because it's very flexible. We can split whenever the element is even, so we use 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],[]]

but we want to condense multiple delimiters like 2,22 into a single list instead of having an empty list of odd numbers in between as we have there, so we use the condense modifier:

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],[]]

but let's drop the final blank list that happens because there's another empty list of odds at the end:

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]]

If on the other hand you're implementing this from the ground up, then you'll need to use the break function.

0
votes

Thanks @AndrewC for answer. I was confused how to split a list and tried to use built in splitWhen function for that. But actually I found solution that do not use splitWhen function but uses prelude function.

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

This solved my problem although it was not as I asked in the question