是否可以进行搜索并替换'在一个有区别的联盟上,例如用Foo
替换Bar
,例如。
type Expression
| Foo of Expression list
| Bar of Expression list
高度嵌套的表达式定义可以有任何深度。
答案 0 :(得分:5)
语言中没有内置功能可以让您自动执行此操作。基本方法是编写递归函数 - 如果要为Foo
切换Bar
,这很容易:
let rec switch = function
| Foo es -> Bar(List.map switch es)
| Bar es -> Foo(List.map switch es)
您可以尝试从指定应该如何转换的位开始抽象遍历树的部分。这并不能解决这个简单的问题,但它对于更复杂的转换非常有用。
例如,以下函数在所有节点上调用它。如果函数返回Some
,则替换节点:
let rec transform f e =
match f e with
| Some n -> n
| None ->
match e with
| Foo es -> Foo(List.map (transform f) es)
| Bar es -> Bar(List.map (transform f) es)
现在,您可以轻松地将Bar []
替换为Foo []
并保持所有其他表达不变:
Foo [ Bar []; Bar[] ] |> transform (fun e ->
match e with
| Bar [] -> Some(Foo [])
| _ -> None)