在SML

2016-11-15 54 views
2

总结两个部分我有一个定义的数据类型在SML

datatype expression = Constant of int 
        | Variable of string 
        | Operator of string * expression 
        | Pair of expression list 
        | List of expression list 

我因为有一个表格两个部分:

Operator("/", Pair [Constant x, Constant y]) 

Operator("/", Pair [Variable x, Constant y]) 

我需要总结这两个分数并返回一个新分母,它以两个分母的最小公倍数作为分母。
我设法使它工作,但我的代码似乎不必要的复杂和令人费解。有没有办法写这个更短? 我设法到目前为止做:

fun add (a,b) = 
    case (a,b) of 
      (Operator("/", Pair [Constant x1, Constant y1]), 
      Operator("/", Pair [Constant x2, Constant y2])) 
      => Operator("/", Pair [Constant ((x1*((lcm(y1,y2) div y1)))+(x2*(lcm(y1,y2) div y2))), Constant (lcm(y1,y2))]) 
      | (Operator("/", Pair [Variable x1, Constant y1]), 
       Operator("/", Pair [Constant x2, Constant y2 ])) 
       => Operator("/", Pair[ 
         Operator("+", Pair[ 
          Operator("*", Pair[Variable x1, Constant (lcm(y1,y2) div y1)]), 
          Constant (x2* (lcm(y1,y2) div y2)) ]), 
         Constant (lcm(y1,y2))]) 

      | (Operator("/", Pair [Constant x1, Constant y1]), 
       Operator("/", Pair [Variable x2, Constant y2 ])) 
       => Operator("/", Pair[ 
         Operator("+", Pair[ 
          Operator("*", Pair[Variable x2, Constant (lcm(y1,y2) div y2)]), 
          Constant (x1* (lcm(y1,y2) div y2)) ]), 
         Constant (lcm(y1,y2))]) 
      | (Operator("/", Pair [Variable x1, Constant y1]), 
       Operator("/", Pair [Variable x2, Constant y2 ])) 
       => Operator("/", Pair[ 
         Operator("+", Pair[ 
          Operator("*", Pair[Variable x1, Constant (lcm(y1,y2) div y1)]), 
          Operator("*", Pair[Variable x2, Constant (lcm(y1,y2) div y2)])]), 
         Constant (lcm(y1,y2))]) 

回答

4

有没有写这个较短的方法吗?

是的。瞄准最简单的模式。例如。如果你正在建设一个抽象语法树,

fun add (e1, e2) = Operator ("+", Pair [e1, e2]) 

如果你正在评估一个语法树,

fun eval env exp = 
    case exp of 
     Constant i => i 
     | Variable x => lookup x env 
     | Operator (oper, exps) => evalOp env oper (map (eval env) exps) 
     | ... => ??? 

and evalOp env "+" is = foldl op+ 0 is 
    | evalOp env "-" is = foldl op- 0 is 
    | ... 

特别:你可能要重新考虑什么有意义的标值是对,列出了可能评估,如果可能,对和列表应该限制在语法树的某些部分。

通常:每当您的模式匹配更深一级时,匹配情况的数量就会乘以构造函数的数量。一个或两个级别的匹配通常就足够了。如果没有,编写执行更深匹配的帮助函数几乎总是理智的选择。