使用ML中的单位(SML / NJ)

时间:2013-11-24 22:38:47

标签: smlnj ml

我正在尝试创建一个打印二叉树的函数。我的二叉树数据类型如下所示:

    datatype 'a BT = empty | bTree of 'a * 'a BT * 'a BT;

我还创建了一个打印整数的函数,我将用于节点:

    fun printInt n = print (Int.toString n);

正如你所看到的,BT数据类型有3个节点('a,'一个BT,'一个BT),我已经开始制作一个displayTree函数,但是找不到打印出我的printInt函数的单位类型的方法回报。我确信还有其他方法可以做到这一点,但在这种情况下,我将如何返回三个连接的单元类型。这是我到目前为止(我明白@s是不正确的)。

    fun displayTree T =
let
    val bTree (root, left, right) = T;
in
    (printInt root)@ (displayTree left) @ (displayTree right)
end;

我并不担心树的行格式化。我只是不确定如何将我的(printInt root)附加到递归调用。

编辑:

我希望displayTree函数是多态的

2 个答案:

答案 0 :(得分:1)

您必须进行一些更改才能使此代码正常工作:

将树定义更改为:

datatype btree =
                 Empty |
                 Node of int * btree * btree;

printInt函数是简短的,所以在这种情况下我会避免它:

fun displayTree T = 
    case T of 
        Empty               => ""
       |Node(root, left, right) => (Int.toString root) ^ (displayTree left) ^ (displayTree right)

请注意,此函数返回表示树的字符串,因此您可以在需要时打印它。字符串连接由@表示。你在函数中缺少的秘密成分称为“模式匹配”。在这种情况下,您可以避免使用if语句进行模式匹配。

让我们先制作一个多态类型:

datatype 'a btree =
                 Empty |
                 Node of 'a * 'a btree * 'a btree

让这个函数变成多态:

fun displayTree T f = 
    case T of 
        Empty               => ""
       |Node(root, left, right) => (f root) ^ (displayTree left f ) ^ (displayTree right f )

现在你必须定义将你的匿名类型转换为string的函数f。

让我们更进一步,定义相同的函数,返回可以打印的节点值列表:

fun displayTree T f = 
    case T of 
        Empty               => [""]
       |Node(root, left, right) => [f root] @ (displayTree left f) @ (displayTree right f)

您可以将其转为返回unit s的列表a:

fun displayTree T f = 
    case T of 
        Empty               => [print ""]
       |Node(root, left, right) => [print(f root)] @ displayTree left f @ displayTree right f 

但我不明白你打算怎么处理它们。

答案 1 :(得分:1)

您的代码存在一些问题,因此很难知道从哪里开始。如果您希望 printInt 实际打印节点的值并返回 unit ,那么您不希望对结果执行任何操作。您应该简单地丢弃它,并且呼叫应该看起来像

(printInt root; displayTree left; displayTree right)

您可能不需要 let..in..end 块中的括号,但需要分号。

其他问题是您需要在树上进行模式匹配。另外,通过在 displayTree 的主体中包含 printInt ,您只能打印 int bTree 类型的值。如果希望 displayTree 是多态的,则需要传入一个函数来打印节点,因为它取决于节点的类型。如果节点是整数,则传入的函数可以是 printInt ,但对于不同类型的节点则是其他的。