在 StandarML 中使用 case of 提取的一对实数相乘

问题描述 投票:0回答:1

我创建了一个数据类型和一个函数。该函数必须能够根据该对的成员是整数还是实数来进行乘法运算。我可以开始为 Int 工作,但是当我为 Real 添加案例时,它会很麻烦。我被困在这里了。请帮助。

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;
sml smlnj ml
1个回答
0
投票

我假设数据类型如下所示:

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
类型,程序将根本无法编译。而是击中最后一个包罗万象的模式意味着两个两个值不是使用相同的构造函数构建的。您可以更改错误,也可以针对这种情况进行此操作。

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);
© www.soinside.com 2019 - 2024. All rights reserved.