0
votes

I'm a new to haskell, I'm trying to create a function that will take a list on integers and returns a list containing two sublists, the first sublist containing the even number and the other containing the odd numbers. I cannot use even, odd or filter functions. i created my own functions as follows

myodd :: Integer -> Bool
myodd n = rem (abs(n)) 2 == 1

myeven :: Integer -> Bool
myeven n = rem (abs(n)) 2 == 0

segregate [] = ([], [])
segregate [x] = ([x], [])
segregate (x:y:xs) = (x:xp, y:yp) where (xp, yp) = segregate xs

im having trouble trying to use the two first functions and use it on the segregated functions. I have more experience in racket and the function I crated looks like this:

    (define (myeven? x)
  (= (modulo x 2) 0)) 

(define (myodd? x)
  (= (modulo x 2) 1))

(define (segregate xs)
  (foldr (lambda (x b)
           (if (myeven? x)
               (list (cons x (first b)) (second b))
               (list (first b) (cons x (second b))))) '(()()) xs))
3
Your Racket code doesn't make sense. Have you tested it?dfeuer
To me, it looks like your Haskell code and your Racket code are doing two very different things - the Racket code partitions the input list depending on whether the value is odd or even, whereas the Haskell code partitions the input list depending on whether the index of the value is odd or even (errors in the code notwithstanding). Which of the two are you actually trying to achieve?Frank Schmitt
@FrankSchmitt, the Racket code doesn't actually seem to do that. In fact, I'm pretty sure it will throw an error too.dfeuer
@dfeuer That's why I wrote 'errors in the code notwithstanding' - to me, it looks like the code is supposed to do what I described (I may be mistaken, of course).Frank Schmitt
I'm sorry I posted the wrong code. I just fixed (define (myeven? x) (= (modulo x 2) 0)) (define (myodd? x) (= (modulo x 2) 1)) (define (segregate xs) (foldr (lambda (x b) (if (myeven? x) (list (cons x (first b)) (second b)) (list (first b) (cons x (second b))))) '(()()) xs))Luis Fernando Pineda

3 Answers

1
votes

Here's one good way:

segregate [] = ?
segregate (x:xs)
  | myEven x = ?
  | otherwise = ?
  where (restEvens, restOdds) = segregate xs

You could also use

segregate = foldr go ([], []) where
  go x ~(evens, odds)
    | myEven x = ?
    | otherwise = ?
0
votes

A simple way is to run through the list twice using each of your hand-rolled functions as a guard predicate:

segregate :: [Integer] -> ([Integer], [Integer])
segregate [] = ([],[])
segregate xs = (evens, odds)
  where evens = [x | x <- xs, myeven x]
        odds  = [x | x <- xs, myodd x]

Note: your question asked for a list of lists but your pattern matching segregate [] = ([],[]) indicated you wanted a tuple so I gave a tuple solution.

0
votes

If you really need such a function rather than writing it for educational purposes, there is partition in Data.List, so a simple

import Data.List(partition) 

wil get you going.

In the educational case, you can still compare your code, once you're done, with the code of partition.