SML - 错误:if分支的类型不一致

时间:2017-09-30 02:49:07

标签: sml smlnj

我正在尝试编写一个SML函数,该函数返回listViolations(L1,L2)中的结果数组。我特别想要彼此交叉引用每个元素O(n ^ 2),并检查选择是否彼此冲突。可视化:[[1,2],[2,3]]是选项1,[[3,2],[2,1]]是选项2。我会像这样调用listViolations:listViolations([[[1,2],[2,3]],[[3,2],[2,1]]]。

行动计划将是:

fun listViolations(L1, L2) =
    if L1 = [] orelse L2 = []
        then 0
     else totalViolations(transitive_closure(hd(L1)),path(hd(L2)))::[] @ listViolations(L1, tl(L2))::[] @ listViolations(tl(L1), L2)::[];

在这里,我正在检查两个列表的头部,并递归地传递两个尾部,希望创建这样的东西:[3,0,0]。

虽然我在声明函数时收到此错误:

stdIn:726.5-728.136 Error: types of if branches do not agree [overload conflict]
then branch: [int ty]
else branch: int list
in expression:
  if (L1 = nil) orelse (L2 = nil)
  then 0
  else totalViolations (transitive_closure <exp>,path <exp>) ::
       nil @ listViolations <exp> :: <exp> @ <exp> 

我提供了下面的所有其他功能,以表明它们没有任何问题,我只是想知道是否有什么东西我做错了。我知道一个事实

  • totalViolations(transitive_closure(HD(L1)),路径(HD(L2)))
  • listViolations(L1,tl(L2)):: []
  • listViolations(tl(L1),L2):: [];

返回整数。如何从中列出并在此功能中返回?提前谢谢。

//[1, 2] , [1, 2, 3] = 0
//[3, 2] , [1, 2, 3] = 1
fun violation(T, P) =
    if indexOf(hd(T), P) < indexOf(hd(tl(T)), P)  then 0
    else 1;

//[[1, 2], [2, 3]] , [1, 2, 3] = 0
//[[3, 2], [2, 1]] , [1, 2, 3] = 2
fun totalViolations(TS, P) =
    if TS = [] then 0
    else violation(hd(TS), P) + totalViolations(tl(TS), P);

//[[1, 2],[2, 3]] -> [1, 2, 3]
fun path(L) =
    if L = [] orelse L =[[]]
        then []
    else union(hd(L),path(tl(L)));

// [[1, 2],[2, 3]] -> [[1, 2],[2, 3], [1, 3]]
fun transitive_closure(L) = union(L, remove([], closure(L, L)));

附加代码:

fun len(L) = if (L=nil) then 0 else 1+length(tl(L));

fun remove(x, L) =
    if L = [] then []
    else if x = hd(L) then remove(x, tl(L))
    else hd(L)::remove(x, tl(L));

fun transitive(L1, L2) =
    if len(L1) = 2 andalso len(L2) = 2 andalso tl(L1) = hd(L2)::[]
        then hd(L1)::tl(L2)
    else [];

fun closure(L1, L2) =
    if (L1 = [[]] orelse L2 = [[]] orelse L1 = [] orelse L2 = [])
        then [[]]
    else if len(L1) = 1 andalso len(L2) = 1
        then transitive(hd(L1), hd(L2))::[]
    else
        union( union(closure(tl(L1), L2), closure(L1, tl(L2))), transitive(hd(L1), hd(L2))::[]);

1 个答案:

答案 0 :(得分:1)

then的{​​{1}}分支是if,而int分支是整数列表。要在前者中形成列表,请写else(这只是[0]的缩写)。此外,其他分支中的递归调用的结果已经预期返回一个列表,因此0::[]的出现是错误的,因为它形成了一个列表列表。

更多提示:从不与空列表进行比较,这将强制元素类型为相等类型。请改用[]谓词。更好(并且更具可读性),完全避免nullnullhd并使用模式匹配。