我正在做一些练习来帮助我理解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时,为了满足树的类型,我需要做什么?
答案 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)
应该这样做。