0

I have this function:

addBinaryTreeNode((genRandomNumber(100), genRandomNumber(100), genRandomNumber(100)), tree, 1, [])

That returns a data type "binaryTree". It will compile when that is by itself, but when I have it in a function:

generate3DNodeTree(addBinaryTreeNode((genRandomNumber(100), genRandomNumber(100), genRandomNumber(100)), tree, 1, []), numToGen - 1)

...it will not compile, giving me these errors:

stdIn:215.21-215.135 Error: operator and operand don't agree [tycon mismatch]                                                                                                                                                                 
operator domain: (int * int * int) * binaryTree * int * int list                                                                                                                                                                            
operand: ((Random.rand -> int) * (Random.rand -> int) * (Random.rand -> int)) * binaryTree * [int ty] * 'Z list
in expression:addBinaryTreeNode((genRandomNumber 100,genRandomNumber 100,genRandomNumber 100),tree,1,nil)   

The function "generate3DNodeTree" has arguments:

(tree : binaryTree, numToGen : int)

...which are exactly what I'm passing to it. Why doesn't this work?

generate3DNodeTree works if I pass it like so:

generate3DNodeTree(tree, numToGen - 1)

SMLNJ knows that the return type of addBinaryTreeNode is binaryTree, so I don't know what the issue could be.

John Coleman
  • 51,337
  • 7
  • 54
  • 119
EpicBlargh
  • 1
  • 1
  • 5
  • The error message seems pretty explicit: `addBinaryTreeNode` is expecting 3 ints but you are passing it three functions of type `Random.rand -> int`. Thus `genRandomNumber 100` isn't what you think it is. It would help if you show the code for `genRandomNumber`. – John Coleman Feb 17 '17 at 00:08
  • Huh, thought it returned an int explicitly. The code is: `Random.randRange(1, numToGen)`. I tried declaring it to a variable but that still didn't seem to work. – EpicBlargh Feb 17 '17 at 00:46

1 Answers1

1

The problem is that your genRandomNumber doesn't return an int. Instead it returns a function of type Random.rand -> int, where Random.rand is the type of a random number generator. You could change the definition of genRandomNumber so that it evaluates this function at a generator and returns an int.

According to the documentation of the Random structure, the function Random.rand(i,j) creates such a generator. In production code you would want to find a way to seed it from the system clock (which doesn't seem easy in SML) though for testing purposes you can just hard-wire in a specific i and j:

val generator = Random.rand(1,5)
fun genRandomNumber(numToGen) = Random.randRange(1, numToGen) generator;

Using these definitions, genRandomNumber is now a function of type int -> int, hence using this definition you won't have the same type mismatch error.

John Coleman
  • 51,337
  • 7
  • 54
  • 119