在SML

2016-11-15 55 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 
    | ... 

特別:你可能要重新考慮什麼有意義的標值是對,列出了可能評估,如果可能,對和列表應該限制在語法樹的某些部分。

通常:每當您的模式匹配更深一級時,匹配情況的數量就會乘以構造函數的數量。一個或兩個級別的匹配通常就足夠了。如果沒有,編寫執行更深匹配的幫助函數幾乎總是理智的選擇。