Search code examples
smlsmlnj

What is the effect of adding a variable type binding in signature in SML on the Module?


In the following code:

signature DIGIT = 
sig
  type digit
  val make_digit : int -> digit
  val increment : digit -> digit
  val decrement : digit -> digit
  val down_and_up : digit -> digit
  val test : digit -> unit
end

structure Digit :> DIGIT =
struct
  type digit = int
  exception BadDigit
  exception FailTest
  fun make_digit i = if i < 0 orelse i > 9 then raise BadDigit else i
  fun increment d = if d=9 then 0 else d+1
  fun decrement d = if d=0 then 9 else d-1
  val down_and_up = increment o decrement (* recall o is composition *)
  fun test d = if down_and_up d = d then () else raise FailTest
end

I run Digit.test 10; in SML compiler for two different cases, of the line type digit in the aforementioned code:

  1. In case of type digit :
Error: operator and operand don't agree [overload conflict]
  operator domain: Digit.digit
  operand:         [int ty]
  1. In case of type digit = int: uncaught exception FailTest

My question is simply, what difference does it make when we inserted = int so that the output/error is different?


Solution

  • The first one is a type error because you haven't specified what the digit type is in this structure.

    The second raises an exception as a runtime error because increment (decrement 10) is 0.

    (I would consider it a design problem that you can use any of the functions with any int, not just things that have been validated by make_digit.)