I create a datatype and a function. The function must be able to do a multiplication according to whether the members of the pair are int(s) or real(s). I can get to work for Int, but when I add a case for Real it borks. I'm stuck here. Please help.
fun f1(pair: numberType * numberType) =
let
val p1 = #1 pair
val p2 = #2 pair
in
case (p1, p2) of
(Int i1, Int i2) => Int.toInt i1 * Int.toInt i2
| (Real r1, Real r2) => r1 * r2
| _ => raise Fail "Neither p1 nor p2 is of type Int or Real"
end;
I'm going to assume the data type looks like the following:
datatype numberType =
Int of int
| Real of real;
All functions must have the same return type. In your function, when you pass in a tuple of Int
values, you return an int
. When you pass in a tuple of Real
values, you return a real
value. This cannot compile.
Rather, you want to return a value of numberType
built with the appropriate constructor for the data passed in.
fun f1(pair: numberType * numberType) =
let
val p1 = #1 pair
val p2 = #2 pair
in
case (p1, p2) of
(Int i1, Int i2) => Int (i1 * i2)
| (Real r1, Real r2) => Real (r1 * r2)
| _ => raise Fail "Neither p1 nor p2 is of type Int or Real"
end;
This will compile but you've been much more verbose than you need to be. Let's start improving.
fun f1(n1, n2) =
case (n1, n2) of
(Int i1, Int i2) => Int (i1 * i2)
| (Real r1, Real r2) => Real (r1 * r2)
| _ => raise Fail "Neither p1 nor p2 is of type Int or Real";
But we can pattern match without that case
expression.
fun f1(Int i1, Int i2) = Int (i1 * i2)
| f1(Real r1, Real r2) = Real (r1 * r2)
| f1 _ = raise Fail "Neither p1 nor p2 is of type Int or Real";
Your error isn't quite right though. The program will not compile at all if the arguments are not of type numberType
. Rather hitting this last catchall pattern at runtime means the two values are not built using the same constructor. You can either change the error, or make this work for such a situation.
Presumably in this case the expected output would be a Real
value.
fun f1(Int i1, Int i2) = Int (i1 * i2)
| f1(Real r1, Real r2) = Real (r1 * r2)
| f1(Int i1, Real r2) = Real (Real.fromInt i1 * r2)
| f1(n1, n2) = f1(n2, n1);