Search code examples
functional-programmingsmlsmlnj

how to split a list into two lists in which the first has the positive entries and the second has non-positive entries-SML


I am a new to SML and I want to write a function splitup : int list -> int list * int list that given a list of integers creates from two lists of integers, one containing the non-negative entries, the other containing the negative entries. Here is my code :

fun splitup (xs :int list) =
  if null xs
  then ([],[])
  else if hd xs < 0
  then hd xs :: #1 splitup( tl xs)
  else hd xs :: #2 splitup( tl xs)

Here's the warning i get:

ERROR : operator and operand don't agree
ERROR : types of if branches do not agree

The function splitup(tl xs) should return int list * int list so i think my recursion should be all right. What is the problem and how can i fix it ?


Solution

  • The problem is that

    hd xs :: #1 splitup( tl xs)
    

    and

    hd xs :: #2 splitup( tl xs)
    

    are lists – you can tell from the :: – not pairs of lists as the result should be.

    For the non-empty case, you need to first split the rest of the list, then attach the head to the correct part of the result and add it the other part of the result in a pair.
    It's also a good idea to get used to pattern matching, as it simplifies code lot.

    Something like this:

    fun splitup [] = ([], [])
      | splitup (x::xs) = let (negatives, non_negatives) = splitup xs
                          in if x < 0 
                             then (x :: negatives, non_negatives)
                             else (negatives, x :: non_negatives)
                          end