Search code examples
smlsmlnjcustom-data-type

How to Sum of Custom datatype of int in SML?


I'm new to SML and are playing with datatypes and such, I have this datatype for example:

datatype test = UInt of int

As far as I understand, UInt should work just like a normal int, but I cannot make it do simple things like sum 2 UInt:

val x = UInt(2)
val y = UInt(3)
val z = x + z

This code gives me this error:

= stdIn:4.11 Error: overloaded variable not defined at type
  symbol: +
  type: test

How can I make this work?

Thanks!


Solution

  • By default, + is defined for two types -- ints and reals, with type int * int -> int and real * real -> real, respectively. It is not defined for your type test.

    You can redefine + to work on the test type as follows:

    val (op+) = fn (UInt x, UInt y) => UInt (x + y)
    

    However, redefining built-ins is generally not the best idea. You could also define a function that will take any int * int -> int function and give you a test * test -> test function that behaves as expected as follows:

    fun lift f = fn (UInt x, UInt y) => UInt (f(x,y))
    

    Using this method, you could define addition for your test type as val liftedAdd = lift (op+), and use this sort of function for all of your work with the test type.

    However, there isn't much good reason to create a datatype that is simply a wrapper for an already existing type with no additional information. You might be looking for the type keyword, which will define a new type to be equal to one that already exists.

    For example, if you say:

    type test = int
    val x : test = 2
    val y : test = 3
    val z = x + y
    

    The addition will work, because while both x and y are tests, and + is defined on ints, test is simply an alias for int.