了解标准ML中多态类型的传递

时间:2015-10-19 14:00:22

标签: functional-programming sml

我正在做一些练习来帮助我理解SML,并发现我很难理解泛型/多态类型如何传递到函数中。

我获得了以下初始信息:

datatype 'a tree = Leaf | Node of 'a tree * 'a * 'a tree


val testTree = Node (Node (Node (Leaf, ("a", 107), Leaf), ("c", 417), Node (Leaf, ("e", ~151), Node (Leaf, ("o", ~499), Leaf))), ("s", 35), Node (Leaf, ("u", ~387), Node (Leaf, ("y", 263), Leaf)))

fun nameCompare (n1: name, n2: name) : order = String.compare (n1, n2)

fun treeLookup cmp =
let
  fun lkup (x, btree) =
     case tree of
        Leaf => NONE
      | Node (lt, y, rt) =>
           (case cmp (x, y) of
               LESS => lkup (x, lt)
             | EQUAL => SOME y
             | GREATER => lkup (x, rt))
in
  lkup
end

当我尝试拨打treeLookup时,我继续收到类型匹配错误。 例如,这就是我所说的

treeLookup nameCompare ("a", testTree)

和我得到这样的错误

treeLookup nameCompare ("a", testTree);
                             ^^^^^^^^
Type clash: expression of type
(string * int) tree
cannot have type
string tree

在将树传递给treeLookup时,为了满足树的类型,我需要做什么?

2 个答案:

答案 0 :(得分:1)

在你的树上

a' : ("a", 107)

treeLookup会在每个元素和您传递的元素上调用cmp。你传入了nameCompare,它带有两个字符串和一个字符串,"a"是一个字符串。这意味着你的树应该只有字符串。

要解决这个问题,你可能想让你的树成为一张地图,有效地只比较该对的第一个值:

| Node (lt, (k,v), rt) =>
           (case cmp (x, k)

也可能改变定义:

datatype 'k 'v tree = Leaf | Node of 'k 'v tree * ('k * 'v) * 'k 'v tree

或者,您可以更改比较功能以('a * 'b),但这意味着,例如您需要treeLookup使用元素("a", 107)来尝试匹配两个字段。

答案 1 :(得分:0)

您正在将字符串与树中的项目进行比较,该项目为string * int

您可以随时更改比较功能;

之类的东西
fun nameCompare (n, (k,v)) = String.compare (n1, k)

应该这样做。