如何将列表拆分为两个列表,其中第一个列表具有正条目,第二个列表具有非正条目-SML

时间:2017-05-14 09:09:51

标签: functional-programming sml smlnj

我是SML的新手,我想写一个函数splitup:int list -> int list * int list给出一个整数列表,它由两个整数列表创建,一个包含非负项,另一个包含负项。 这是我的代码:

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)

这是我得到的警告:

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

函数 splitup(tl xs) 应该返回int list * int list所以我认为我的递归应该没问题。 有什么问题,如何解决?

2 个答案:

答案 0 :(得分:1)

问题在于

hd xs :: #1 splitup( tl xs)

hd xs :: #2 splitup( tl xs)

是列表 - 你可以从::告诉 - 不应该是结果列表对。

对于非空的情况,您需要首先拆分列表的其余部分,然后将头部附加到结果的正确部分,并将结果的其他部分添加到一对中。
习惯模式匹配也是一个好主意,因为它简化了代码批次。

这样的事情:

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

答案 1 :(得分:1)

已经有List.partition : ('a -> bool) -> 'a list -> 'a list * 'a list,这是一个更高阶的库函数。如果你想将整数分成(负数,非负数):

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