为什么合并排序函数会发生值限制



我在List上有一个非常简单的MergeSort实现。

/// Divide the list into (almost) equal halves
let rec split = function
    | [] -> [], []
    | [x] -> [x], []
    | x1::x2::xs -> let xs1, xs2 = split xs
                    x1::xs1, x2::xs2
/// Merge two sorted lists
let rec merge xs ys =
    match xs, ys with
    | [], _ -> ys
    | _, [] -> xs
    | x::xs', y::ys' when x <= y -> x::merge xs' ys
    | _, y::ys' -> y::merge xs ys' 
let rec mergeSort = function
    | [] -> []
    | xs -> let xs1, xs2 = split xs
            merge (mergeSort xs1) (mergeSort xs2)

但是每当我尝试使用 F# 交互式中的任何输入进行测试时:

let xs = mergeSort [1;4;3;2];;

我遇到了值限制错误:

错误 FS0030:值限制。值"xs"已推断为 具有泛型类型 val xs : '_a 当 '_a 时列出:比较 要么将"xs"定义为一个简单的数据项,使其成为具有显式参数的函数,或者,如果 您不希望它是泛型的,请添加类型注释。

为什么会这样?修复它的简单方法是什么?

您没有处理 mergeSort 中 1 元素列表的特殊情况。一般情况"太笼统",无法推断出正确的类型。因此,编译器推断函数的泛型类型太泛型('a list -> 'b list),结果始终是泛型列表(由于值限制,不允许这样做)。

如果这样修复它,该类型将被正确推断为"列表 ->列表"。

let rec mergeSort = function
    | [] -> []
    | [x] -> [x]
    | xs -> let xs1, xs2 = split xs
            merge (mergeSort xs1) (mergeSort xs2)

相关内容

  • 没有找到相关文章

最新更新