F#表达式树中的替换表达式

F#表达式树中的替换表达式,f#,tree,F#,Tree,给定类型为的表达式树: type Fexpr = | Const of float | X | Add of Fexpr * Fexpr | Sub of Fexpr * Fexpr | Mul of Fexpr * Fexpr | Div of Fexpr * Fexpr 我想做一个函数,用另一个表达式替换树中的一个表达式。例如: substX:Fexpr->Fexpre->Fexpr 这样subtx e'e从e返回表达式,其中X的每次出现都被

给定类型为的
表达式树

type Fexpr =
    | Const of float
    | X
    | Add of Fexpr * Fexpr
    | Sub of Fexpr * Fexpr
    | Mul of Fexpr * Fexpr
    | Div of Fexpr * Fexpr
我想做一个函数,用另一个表达式替换树中的一个表达式。例如:

substX:Fexpr->Fexpre->Fexpr

这样
subtx e'e
e
返回表达式,其中
X
的每次出现都被
e'
替换:

let ex = (Mul,X, Add(Const 2.0, X))

substX (Div(X,X)) ex 
会回来吗

(Mul,Div(X,X),Add(Const 2.0,Div(X,X))


我不完全确定从何处开始,因此任何提示都值得赞赏。

由于您的函数输入是一种求和类型(也称为“判别联合”),因此您的函数必须包含关于如何处理每种求和情况的指令。为此,F提供了一种称为“模式匹配”的功能:

现在,让我们看一下这些情况:如果输入是
Const
,那么输出应该是相同的
Const
-其中没有什么可以替代的。如果输入是
X
,那么输出应该是我们要替代的任何东西-这就是函数的全部要点。到目前为止,很好。让我们把它写下来:

let substEx subst ex = match ex with
   | Const c -> Const c
   | X -> subst
    ...
好的,现在我们如何处理
Add
?在
Add
表达式中替换
X
的结果也是一个
Add
表达式,其参数是在原始
Add
的参数中替换
X
的结果。但是我如何在参数中替换
X
呢?如果只有这是一个函数…哦,等一下!这正是我们目前正在编写的函数!让我们把它写下来:

let rec substEx subst ex = match ex with
   | Const c -> Const c
   | X -> subst
   | Add r l -> Add (substEx subst r) (substEx subst l)
    ...
注意函数声明中的
rec
,它代表“recursive”,是必需的,因为我们的函数现在正在调用自己

最后,让我们对
Sub
Mul
Div
做同样的事情,我们完成了:

let rec substEx subst ex = match ex with
   | Const c -> Const c
   | X -> subst
   | Add r l -> Add (substEx subst r) (substEx subst l)
   | Sub r l -> Sub (substEx subst r) (substEx subst l)
   | Mul r l -> Mul (substEx subst r) (substEx subst l)
   | Div r l -> Div (substEx subst r) (substEx subst l)
调查
let rec substEx subst ex = match ex with
   | Const c -> Const c
   | X -> subst
   | Add r l -> Add (substEx subst r) (substEx subst l)
   | Sub r l -> Sub (substEx subst r) (substEx subst l)
   | Mul r l -> Mul (substEx subst r) (substEx subst l)
   | Div r l -> Div (substEx subst r) (substEx subst l)