【问题标题】:SML merge_sort function using let in and pattern matching使用 let in 和模式匹配的 SML merge_sort 函数
【发布时间】:2020-06-11 21:35:10
【问题描述】:
fun merge_sort (_, nil) = nil
  | merge_sort (_, [a]) = [a]
  | merge_sort (f, L)   =
    let
        fun halve nil = (nil,nil)
          | halve [a] = ([a], nil)
          | halve (a :: b :: rest) =
            let
                val (x , y) = halve rest
            in
                (a :: x, b :: y)
            end
        fun merge (f, nil, x) = x
          | merge (f, x, nil) = x
          | merge (f, a::b, x::y) =
            if f(a, b) then a :: merge (f, b, x::y)
                       else x :: merge (f, a::b, y);
        val (x, y) = halve L
    in
        merge(f, merge_sort(f, x), merge_sort(f,y))
    end;

merge_sort (op <) [2,1,3,2,4,3,45];

这是我一直在研究的一个 SML 函数。它旨在进行底部所示的函数调用并进行合并排序。必须是一个函数。我正在努力理解模式匹配以及如何充分发挥这个功能。

我在编译和运行时收到此错误代码。

$sml < main.sml
Standard ML of New Jersey v110.78 [built: Thu Aug 31 03:45:42 2017]
- val merge_sort = fn : ('a * 'a list -> bool) * 'a list -> 'a list
stdIn:23.1-23.35 Error: operator and operand don't agree [tycon mismatch]
  operator domain: ('Z * 'Z list -> bool) * 'Z list
  operand:         [< ty] * [< ty] -> bool
  in expression:
    merge_sort <
- 

我不完全知道我做错了什么

【问题讨论】:

    标签: sorting pattern-matching sml


    【解决方案1】:

    使用复数“s”命名列表的约定,并在模式中为头部和尾部使用相同的基本名称会使问题立即突出:

    merge (f, x::xs, y::ys) =
            if f(x, xs) then x :: merge (f, xs, y::ys)
                        else y :: merge (f, x::xs, ys);
    

    f(x, xs) 当然应该是f(x, y)

    这个约定是传统的,因为它很有用。不要没有它就离开家。

    【讨论】:

      【解决方案2】:

      你有一个错字;这个:

                  if f(a, b) then a :: merge (f, b, x::y)
                             else x :: merge (f, a::b, y);
      

      应该是这样的:

                  if f (a, x) then a :: merge (f, b, x::y)
                              else x :: merge (f, a::b, y)
      

      (在(a, x)而不是(a, b)上调用f)。

      由于bx 具有不同的类型(分别为'Z list'Z),这个错字的结果是f 被推断为具有错误的类型('Z * 'Z list -&gt; bool 而不是@ 987654332@),因此整个 merge_sort 函数被推断为具有错误的类型方案(('a * 'a list -&gt; bool) * 'a list -&gt; 'a list 而不是 ('a * 'a -&gt; bool) * 'a list -&gt; 'a list)。

      一些显式的类型注释(例如在一个地方写f : 'a * 'a -&gt; bool)可能使编译器更容易帮助您查看您偏离预期类型的​​位置;但是,诚然,如果您还不知道自己偏离了哪里,那么可能很难弄清楚在哪里添加注释,以便编译器可以帮助您找到偏离的地方。

      【讨论】:

        猜你喜欢
        • 2012-09-02
        • 2017-06-10
        • 1970-01-01
        • 2020-07-30
        • 1970-01-01
        • 2013-01-14
        • 1970-01-01
        • 2013-01-11
        • 2012-09-13
        相关资源
        最近更新 更多