英文:
Multiplying real number extracted of a pair using case of in StandarML
问题
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 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;
答案1
得分: 2
以下是翻译的内容:
我将假设数据类型如下所示:
datatype numberType =
Int of int
| Real of real;
所有函数必须具有相同的返回类型。在你的函数中,当你传入Int
值的元组时,你返回一个int
。当你传入Real
值的元组时,你返回一个real
值。这是无法编译的。
相反,你应该返回一个numberType
值,使用适当的构造函数来构建传入的数据。
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;
这将编译,但你比需要的更冗长。让我们开始改进。
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";
但我们可以不使用case
表达式进行模式匹配。
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";
不过你的错误提示不太对。如果参数不是numberType
类型,程序将根本无法编译。而在运行时命中最后的通用模式,意味着这两个值不是使用相同的构造函数构建的。你可以要么更改错误提示,要么使其适用于这种情况。
在这种情况下,预期输出应该是一个Real
值。
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);
英文:
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);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论