Search code examples
smlsmlnj

Product of Tree Elements SMLNJ


I have the following qtree datatype:

datatype 'a qtree = Leaf of 'a
|   Node of 'a branches
and 'a branches = Empty
|   Branch of 'a qtree * 'a branches

An example tree is defined as follows:

val tr1 = 
Node(Branch(Leaf(2),
    Branch(Node(Branch(Leaf(6),
    Branch(Leaf(5),Empty))),
Branch(Node(Empty),Empty))))

Here is a visual representation of tr1:

  /|\
 / | \
2 / \
 /   \
6     5

I have defined the following function tree_prod to find the product of the values in a qtree:

fun tree_prod(Leaf(n)) = n
|   tree_prod(Empty) = 1
|   tree_prod(Node(br)) = tree_prod(br)
|   tree_prod(Branch(n, br)) = tree_prod(n) * tree_prod(br)

But I am receiving the following errors, which seem to occur due to a type mixup between qtree and branches:

stdIn:10.5-13.42 Error: parameter or result constraints of clauses don't 
agree [tycon mismatch]
  this clause:      'Z branches -> 'Y
  previous clauses:      'X qtree -> 'Y
  in declaration:
    tree_prod =
      (fn Leaf n => n
         | Empty => 1
         | Node br => tree_prod br
         | Branch (<pat>,<pat>) => tree_prod <exp> * tree_prod <exp>)
stdIn:10.5-13.42 Error: parameter or result constraints of clauses don't 
agree [tycon mismatch]
  this clause:      'Z branches -> 'Y
  previous clauses:      'X qtree -> 'Y
  in declaration:
    tree_prod =
      (fn Leaf n => n
        | Empty => 1
        | Node br => tree_prod br
        | Branch (<pat>,<pat>) => tree_prod <exp> * tree_prod <exp>)
stdIn:12.19-12.27 Error: operator and operand don't agree [tycon mismatch]
  operator domain: [int ty] qtree
  operand:         [int ty] branches
  in expression:
    tree_prod br
stdIn:13.24-13.42 Error: operator and operand don't agree [tycon mismatch]
  operator domain: [int ty] qtree
  operand:         [int ty] branches
  in expression:
    tree_prod br

How do I fix these errors?

Bonus: How do I implement this function using fold?


Solution

  • I have located the answer on my own. By dividing this into two separate functions, I am able to specify which types I am wanting to work with.

    Here is the working solution:

    fun tree_prod (Leaf(n)) = n
    |   tree_prod (Node(br)) = branches_prod(br)
    and branches_prod (Empty) = 1
    |   branches_prod (Branch(n, br)) =
        tree_prod(n) * branches_prod(br)