【问题标题】:SML - Error: types of if branches do not agreeSML - 错误:if 分支的类型不一致
【发布时间】:2017-10-01 05:04:53
【问题描述】:

我正在尝试编写一个 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)),path(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))::[]);

【问题讨论】:

    标签: sml smlnj


    【解决方案1】:

    ifthen 分支是 int,而 else 分支是整数列表。要在前者中形成一个列表,请写 [0](它只是 0::[] 的缩写)。此外,在另一个分支中递归调用的结果已经预计会返回一个列表,因此与 [] 的 consing 是错误的,因为它形成了一个列表列表。

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

    【讨论】:

    • - 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)::[] stdIn:649.2-734.136 错误:子句的右侧没有'不同意函数结果类型 [tycon mismatch] 表达式:int 列表结果类型:int 声明:listViolations = (fn (L1,L2) => if orelse then :: else :: ) 我需要什么来获得所需的输出,一个整数列表?
    • 去掉两次递归调用后的::[]
    • 对不起,我累了,我仍然遇到错误。你能告诉我工作版本的代码吗?
    猜你喜欢
    • 2013-08-31
    • 2021-10-16
    • 1970-01-01
    • 1970-01-01
    • 2010-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-28
    相关资源
    最近更新 更多