处理整数数据类型是否有更有效的方法?

时间:2016-11-11 23:21:10

标签: types pattern-matching sml

我有以下代码:

datatype eInt = infinity of int | 0 | Int of int;

exception undefined;
fun eAdd(e1:eInt, 0:eInt) = e1
  | eAdd(0, e2) = e2
  | eAdd(e1, infinity) = infinity
  | eAdd(infinity, e1) = infinity
  | eAdd(infinity, ~infinity) = raise undefined
  | eAdd(~infinity, infinity) = raise undefined
  | eAdd(e1, e2) = e1 + e2;

有一种新的数据类型允许三种类型:infinity,0和int。我认为0在这里可能是多余的,但我不确定。

我使用模式匹配来制定将两个eInt加在一起的不同类型的可能结果。

有四种不同的结果。

  • 如果有0,则返回其他int
  • 如果有∞,则返回∞
  • 如果有∞和-∞,则返回undefined
  • 还有其他任何东西,还要添加其中两个

我能想到的唯一能使这种算法更有效的方法是,如果我要删除双重情况,最后在反转(e1,e2)之后再次运行算法(e2,e1)。 / p>

有关提高效率的想法吗?我将添加其他操作,如分区,这将有更多的情况。

2 个答案:

答案 0 :(得分:2)

  1. 是的,0是多余的,因为您还有Int 0

  2. 使用大写构造函数名称。

  3. 你还没有真正说出Infinity of int的意思。从你的例子来看,你只关心无穷大是积极还是消极,所以 int 也是多余的。

  4. 使用选项类型而不是使用例外。

  5. 总之,你可能有

    datatype IntExt = PosInf
                    | NegInf
                    | Int of int
    
    fun extAdd (PosInf, i2) = if i2 = NegInf then NONE else SOME PosInf
      | extAdd (i1, PosInf) = if i1 = NegInf then NONE else SOME PosInf
      | extAdd (NegInf, _) = SOME NegInf
      | extAdd (_, NegInf) = SOME NegInf
      | extAdd (Int a, Int b) = SOME (Int (a+b))
    

    如果您想要有效的实现,请考虑将整数编码为IEEE 754

答案 1 :(得分:1)

  • 我删除了“recursion”标记,因为此函数没有递归。
  • 如果您特别担心效率,请从最常见到最不频繁地订购条款。这可能意味着您的“未定义”条款将持续使用。
  • 检查选择条款的相对效率。花费时间来评估参数并切换一半时间可能会消耗更短代码所带来的任何节省。