SML:错误:非构造函数应用于模式中的参数: -

时间:2018-06-15 09:01:18

标签: sml smlnj

我正在为MOOC写这个函数。它的作用是从string中删除list并返回该列表而不将字符串作为SOME或返回NONE是字符串不存在。 我编写了下面的代码,但每当我尝试运行它时,我都会收到以下错误:Error: non-constructor applied to argument in pattern: -

exception NotFound

fun all_except_option (str : string, strs : string list) =
    let
        fun remove_str (strs : string list) =
            case strs of
                []          => raise NotFound
              | str'::strs' => if same_string(str, str') then strs' else str'::remove_str strs'
    in
        SOME (remove_str strs) handle NotFound => NONE
    end

在哪里进行一次测试:

val test01-01 = all_except_option ("string", ["string"]) = SOME []

修改

忘记包含提供给我们的same_string函数来简化类型

fun same_string(s1 : string, s2 : string) =
    s1 = s2

2 个答案:

答案 0 :(得分:2)

找出问题所在。似乎val test01-01 = all_except_option ("string", ["string"]) = SOME []不喜欢连字符,就像我在测试中那样:

val test01_01 = all_except_option ("string", ["string"]) = SOME []

我改为强调而现在它起作用了。

--grandle

答案 1 :(得分:2)

由于您已经解决了这项任务,因此可以在不使用例外的情况下编写该任务:

fun all_except_option (_, []) = NONE
  | all_except_option (t, s :: ss) =
      if s = t
      then SOME ss (* don't include s in result, and don't recurse further *)
      else case all_except_option (t, ss) of
                SOME ss' => SOME (s :: ss')
              | NONE     => NONE

使用递归函数返回 t选项而不是 t 会使处理变得更加困难,因为在每次递归调用时,都必须检查它是否返回{{1 }或SOME ...。这可能意味着很多案例... ... s!

可以使用库函数NONE将它们抽象出来。该定义可在the standard library中找到,并转换为:

Option.map

这个位类似于fun (*Option.*)map f opt = case opt of SOME v => SOME (f v) | NONE => NONE 中的案例... ... ;重写它看起来像:

all_except_option