为什么我的'a list *'类型的功能是一个列表 - > 'b列表?

时间:2011-10-29 23:53:10

标签: recursion functional-programming type-inference sml smlnj

我想我希望它是'a list *'类型的列表 - > '列表。

交叉点应该返回两个列表 样本输入和输出:

  • 十字路口([1],[1]);
    • [1]
  • 交叉口([1,2,3],[1,2]);
    • [1,2]
  • 交叉点([[2,3],[1,2],[2,3]],[[1],[2,3]]);
    • [[2,3]]

我的职能:

fun intersection (l1, l2) = let
    fun intersection_acc (acc, [], h::t) = []
        | intersection_acc (acc, h::t, []) = []
        | intersection_acc (acc, h::t, h2::t2) = if in_list (h, l2)
            then intersection_acc (h::acc, t, l2)    
        else intersection_acc (acc, t, l2)
    in intersection_acc ([], l1, l2)
end

我不认为in_list是问题,但看起来像这样:

 fun in_list (x, []) = false
    | in_list (x, y::r) = if x = y 
    then true 
    else in_list (x, r);

1 个答案:

答案 0 :(得分:3)

我的猜测是你在累加器函数中破坏了基本情况

intersection_acc (acc, h::t, []) = []

它可能会返回一些内容,具体取决于acc

intersection_acc (acc, h::t, []) = acc

显示'b list的原因是因为交集将始终返回空列表[]。由于您不使用该空列表,因此编译器需要保守,并说该列表可以是任何类型。


无论如何,你的功能似乎从根本上更加困惑。你其实想要做像

这样的事情
result = []
for each item in list1:
    if item in list2:
        add item to result
return result

使用累加器参数将此命令式代码转换为递归函数:

fun go(acc, []) = acc
  | go(acc, x::xs) =
        if x in list2 then
            go(x::acc, xs)
        else
            go(acc, xs)

完整功能:

fun intersect(list1, list2) = let
    fun go(acc, []) = acc
      | go(acc, x::xs) =
            if x in list2 then
                go(x::acc, xs)
            else
                go(acc, xs)
    in go([], list1)