在Standard ML中使用案例对提取的一对实数进行乘法操作。

huangapple go评论37阅读模式
英文:

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);

huangapple
  • 本文由 发表于 2023年5月14日 09:32:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76245478.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定