0

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 ?

naide
  • 293
  • 3
  • 14
DennngP
  • 37
  • 8

2 Answers2

1

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
molbdnilo
  • 64,751
  • 3
  • 43
  • 82
  • When my recursion comes to the end of the list, it returns pairs of lists and `#1 splitup (xs)` should be a list. So why `:: #1 pairs of lists` will go wrong ? – DennngP May 15 '17 at 02:37
  • @DennngP It goes wrong because it's supposed to be a pair of lists. As the message says, both branches of a conditional must have the same type. – molbdnilo May 15 '17 at 04:26
1

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)
sshine
  • 15,635
  • 1
  • 41
  • 66