0

I am trying to make a function that will print binary trees. My binary tree datatype looks like this:

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

I have also made a function that prints integers, which I will be using for the nodes:

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

As you can see, the BT datatype has 3 nodes ('a,'a BT, 'a BT), I have started making a displayTree function, but cannot find a way to print out the unit types that my printInt function returns. I'm sure that there are other ways to do this, but in this case, how would I return three concatenated unit types. Here is what I have so far (I understand that the @s are incorrect).

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

I am not worried about the line formatting of the trees yet. I am just unsure of how to append my (printInt root) to the recursive calls.

EDIT:

I want the displayTree function to be polymorphic

user2803198
  • 57
  • 1
  • 2
  • 6

2 Answers2

1

You have to make few changes in order to get this code working:

Change tree definition to:

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

printInt function is to short, so I will avoid it in this case:

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

Note that this function returns string that represents tree, so you can print it when needed. String concatenation is represented by @. And the secret ingredient that you was missing in your function is called "pattern matching". In this case you can avoid pattern matching with if statement.

Let's make a polymorphic type first:

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

Let's make this function polymorphic:

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

Now you have to define function f that converts your anonymous type to a string.

Let's go a step further and define same function that returns a list of node values that you can print:

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

And you can turn this to return list a of units:

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

but I don't understand what are you going to do with them.

user987339
  • 10,519
  • 8
  • 40
  • 45
  • I forgot to mention that my `displayTree` function will be polymorphic. I was just showing one type in this example. And string concatenation is `^`, `@` is for lists. – user2803198 Nov 25 '13 at 01:23
1

There are several problems with your code so it's difficult to know where to start. If you want printInt to actually print the value of the node and return unit then you don't want to do anything with the result. You should simply discard it and the calls should look like

(printInt root; displayTree left; displayTree right)

You may not need the parentheses inside the let..in..end block but you need the semicolons.

Other problems are that you need to pattern match on the tree. Also by including printInt in the body of displayTree you are only able to print values of type int bTree. If you want displayTree to be polymorphic you need to pass in a function to print the node since it will depend on the type of the node. The function you pass in could be printInt if the node is an integer but something else for a node of a different type.

David Matthews
  • 516
  • 2
  • 1