【问题标题】:Why am I getting "unbound variable or constructor" in my SML program为什么我的 SML 程序中出现“未绑定的变量或构造函数”
【发布时间】:2017-12-09 11:44:37
【问题描述】:

我编写了一个方法来返回列表中满足函数的第一个元素(通过柯里化传入)。该函数根据元素是否满足条件返回 NONE 或 SOME。我正在使用模式匹配 但是,我遇到了可怕的错误: 错误:未绑定的变量或构造函数:my_function

我是 SML 的新手,我发现最难的事情之一就是理解错误消息。根据以前对该消息的经验,我认为问题在于 my_function 永远不会返回,但我无法在这里看到逻辑问题。有人可以快速查看并告诉我问题吗?当没有满足输入函数 f 的元素时,我提出错误的问题是什么?

我对出了什么问题感兴趣,也许更重要的是,当您看到此类错误时,有什么方法可以获取更多信息?

val  my_function = fn f => fn lst =>  (* Notice currying *)
  case lst of
      [] => raise NoAnswer  (* Get here is nothing in lst saf

    | x::xs => case f(x) of NONE => ( my_function f xs)
                 | SOME y  =>  x 

 val test = my_function(fn x => if x < 3 then SOME x else NONE) [1,2,3,4] = 2

谢谢,戴夫

【问题讨论】:

    标签: sml smlnj


    【解决方案1】:

    如果使用val 关键字声明函数,则无法递归定义该函数。因此,问题就在这里:

    ... NONE => ( my_function f xs) ...
    

    您可以通过在声明中添加rec 关键字来表示您希望递归地定义函数。

    val rec my_function = fn f => fn list => ...
    

    或者,fun 关键字是 val rec 的语法糖。 fun 还包括很好的柯里化语法糖:

    fun my_function f lst = (* This is equivalent to your first line *)
    

    有时您仍然只想使用 val 关键字而不是 val rec。例如,

    val f = fn x => x + 3
    val f = fn y => f y + 4 (* f here refers to the previous declaration of f *)
    

    【讨论】:

    • 感谢您的快速回复。我不知道 val 并且无法递归调用。我用 fun 替换了 val 并得到错误:错误:无法在子句中找到函数参数和错误:子句的右侧与函数结果类型 [tycon 不匹配] 不一致。也许我现在确实有逻辑错误。我会检查一下。
    • “raise NoAnswer”是否会导致问题?这个想法是从满足函数 f 的列表中返回第一个元素,否则抛出异常。不能不返回异常吗?
    • 如果你使用fun而不是val rec,你必须写fun my_function f lst = ...而不是fun my_function = fn f =&gt; fn lst =&gt; ...
    • 哇!作品。谢谢!标记为答案。但是如果你有第二个......你怎么能从错误描述中说出问题所在?第一个错误“未绑定的构造函数...”并没有真正暗示“无法使用 val 进行递归”。而第二个错误“子句的右侧..”并没有真正说明您不能使用 fn f => fn lst。同样,我发现这种对错误的解释对于 ML 来说是最困难的事情。再次感谢。
    • smlnj.org/doc/errors.html 提供了您会收到错误消息的情况示例。对于第二个错误,更相关的消息是“在子句中找不到函数参数”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-12
    • 2015-02-04
    • 2020-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多