DennngP
DennngP

Reputation: 37

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 ?

Upvotes: 0

Views: 1439

Answers (2)

sshine
sshine

Reputation: 16135

There is already List.partition: ('a -> bool) -> 'a list -> 'a list * 'a list, a higher-order library function that does this. In case you want to split up integers into (negative, non-negative):

val splitup = List.partition (fn x => x < 0)

Upvotes: 1

molbdnilo
molbdnilo

Reputation: 66459

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

Upvotes: 1

Related Questions