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:
type digit
:Error: operator and operand don't agree [overload conflict]
operator domain: Digit.digit
operand: [int ty]
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?
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
.)