-1

I need to create a function that will take a list of integers and split them into 2 lists, one with odd numbered and the other even

split :: [a] -> ([a], [a])
split = undefined

Above is the function baseline, below is current attempt I have

 split :: [a] -> ([a], [a])
 split [] = ([],[])
 split (x:xs) | x mod 2 == 0 = ([],[x:split xs])
         | x mod 2 /= 0 = ([x:split xs],[])
         | otherwise = ([],[])
  • 1
    Are you sure you need to check the evenness/oddness of the values of the list elements, and not just their position? I mean, in the latter case you could also run `split [True, False]` and `split "hello"`, as your signature allows. Further, your signature does not allow checking ``x `mod` 2`` since that makes no sense on a non-integral `x`. – chi Sep 30 '21 at 20:55
  • hint: `split (x:xs)` will be either of the form `(x:ys, zs)` or `(ys, x:zs)`, where `(ys, zs)` is the result of `split xs`. You need to write that out in Haskell, and figure out how you decide which of the two cases to use. – Robin Zigmond Sep 30 '21 at 21:26

1 Answers1

1

explicit recursion:

split :: Integral a => [a] -> ([a], [a])
split []        = ([], [])
split (x:xs)
  | even x      = (x:ys, zs)
  | otherwise   = (ys, x:zs)
  where
    (ys, zs) = split xs

implicit recursion:

splitf :: Integral a => [a] -> ([a], [a])
splitf xs = foldr (\x (ys, zs) -> if even x then (x:ys, zs) else (ys, x:zs)) 
                  ([], []) xs

which you can eta reduce to point-free style:

splitf2 :: Integral a => [a] -> ([a], [a])
splitf2 = foldr (\x (ys, zs) -> if even x then (x:ys, zs) else (ys, x:zs)) 
                ([], [])

I think the code is self explanatory. If there is anything I need to further explain, please let me know.

Will Ness
  • 70,110
  • 9
  • 98
  • 181
user1984
  • 5,990
  • 2
  • 13
  • 32