2017-02-20 62 views
1

下面的簡化函數試圖簡化類型
((2 + 3) * (2 + 4))
的數學表達式來
(2 * (3 + 4))如何使用有源圖案來實現的數學表達式簡化

理想情況下,我想寫出匹配表達式爲:

| Product (Sum (c, a), Sum (c, b)) -> Product (c, Sum (a, b)) 

但是,這給我的「C在這種模式勢必兩次」錯誤。所以我訴諸守衛條件。

我想知道是否有更好的方法來使用主動模式來實現這一點?

type Expr = 
    | Number of int 
    | Sum  of Expr * Expr 
    | Product of Expr * Expr 

let rec eval = 
    function 
    | Number n  -> n 
    | Sum (l, r)  -> eval l + eval r 
    | Product (l, r) -> eval l * eval r 

let rec show = 
    function 
    | Number n  -> n.ToString() 
    | Sum (l, r)  -> "(" + show l + " + " + show r + ")" 
    | Product (l, r) -> "(" + show l + " * " + show r + ")" 

let rec simplify = 
    function 
    | Product (Sum (c, a), Sum (d, b)) when (c = d) -> Product (c, Sum (a, b)) 
    | Sum (l, r)  -> Sum (simplify l, simplify r) 
    | Product (l, r) -> Product (simplify l, simplify r) 
    | e -> e 

let c = Product (Sum (Number 2, Number 3), Sum (Number 2, Number 4)) 
show c 
eval c 
show (simplify c) 
+4

您擁有它的方式是正確的,沒有簡短的符號。 –

+5

你如何「簡化」(2 + 3)*(2 + 4)'等於'30'到'2 *(3 + 4)'等於'14'?這些東西並不等同。 – TheInnerLight

+0

[「Expert F#4.0」](http://www.worldcat.org/oclc/936182944)有關於[簡化代數表達式]的章節(https://books.google.com/books?id=XKhPCwAAQBAJ&pg=PA339&lpg = PA339&DQ =專家+ F%23 + 4.0 +簡化+代數+表達。&源= BL&OTS = GHXjjeHPbV&SIG = I4wbdiF6WVWOx4EdES6KS4ohh7M&HL = EN&SA = X&VED = 0ahUKEwio54a0jKHSAhXC1CYKHQemCd4Q6AEIITAB#v = onepage&q =專家%20F%23%204.0%20Simplifying%20Algebraic%20Expressions。&F = false)這可能有幫助。 –

回答

3

我不知道該主動模式是更好,但他們可以在比賽中陳述更聲明,讓你掰開每一種情況下。

這裏是一個使用活動模式的版本,我也修復了邏輯。請注意它是如何更詳細的:

type Expr = 
    | Number of int 
    | Sum  of Expr * Expr 
    | Product of Expr * Expr 

let rec eval = 
    function 
    | Number n  -> n 
    | Sum (l, r)  -> eval l + eval r 
    | Product (l, r) -> eval l * eval r 

let rec show = 
    function 
    | Number n  -> n.ToString() 
    | Sum (l, r)  -> "(" + show l + " + " + show r + ")" 
    | Product (l, r) -> "(" + show l + " * " + show r + ")" 

let (|CommonFactor|_|) = 
    function 
    | Sum (Product (a, b), Product (c, d)) when (a = c) -> Some <| Product (a, Sum (b, d)) 
    | Sum (Product (a, b), Product (c, d)) when (a = d) -> Some <| Product (a, Sum (b, c)) 
    | Sum (Product (a, b), Product (c, d)) when (b = c) -> Some <| Product (b, Sum (a, d)) 
    | Sum (Product (a, b), Product (c, d)) when (b = d) -> Some <| Product (b, Sum (a, c)) 
    | _ -> None 

let (|Operation|_|) simplify = 
    function 
    | Sum (l, r)  -> Some <| Sum (simplify l, simplify r) 
    | Product (l, r) -> Some <| Product (simplify l, simplify r) 
    | _ -> None 

let (|Constant|_|) = 
    function 
    | Number _ as n -> Some n 
    | _ -> None 

let rec simplify = 
    function 
    | CommonFactor exp -> simplify exp 
    | Operation simplify exp -> exp 
    | Constant exp -> exp 
    | _ -> failwith "Oh teh noes!" 

let c = Sum (Product (Number 2, Number 3), Product (Number 2, Number 4)) 
show c |> Dump 
eval c |> Dump 
show (simplify c) |> Dump 
+0

謝謝,這就是我正在尋找對於。什麼是轉儲btw。 –

+0

我正在使用LinqPad,所以基本上打印它 – Stuart