假设我有一个新的“大”类型。 例如,假设我的类型是«formule»:
type formule =
|VRAI
|Predicat of char
|NON of formule
|ET of formule * formule
|OU of formule * formule
|X of formule
|G of formule
|F of formule
|U of formule * formule
现在,我需要一个可以计算“公式”类型大小的函数。为了做到这一点,我们可以使用相同的算法来计算二叉树的节点数。这里的问题是,如果我执行模式匹配,则必须处理很多情况,这很烦人。
如果我可以像下面的«taille»函数那样对参数的数量进行模式匹配,那将是很好的:
let rec taille = function
|VRAI || Predicat(_) -> 1
|_(a) -> 1 + taille a
|_(a,b) -> 1 + taille a + taille b
问题是这不起作用。当我编译以下代码时:
type formule =
|VRAI
|Predicat of char
|NON of formule
|ET of formule * formule
|OU of formule * formule
|X of formule
|G of formule
|F of formule
|U of formule * formule
let rec taille = function
|VRAI || Predicat(_) -> 1
|_(a) -> 1 + taille a
|_(a,b) -> 1 + taille a + taille b
我收到以下错误:
File "main.ml", line 1, characters 192-195:
Error: Syntax error
我认为它来自我的模式匹配,这是不正确的,但是在这种情况下,为什么我在第一行出现错误?
此外,如果确实来自我的模式匹配,那么有一种方法可以像«taille»一样进行模式匹配(对参数数量进行模式匹配以减少案例数)。 / p>
谢谢!
答案 0 :(得分:4)
您不能在这样的模式下使用二进制析取运算符。但是,有一个模式匹配快捷方式可以满足您的需求:
let rec taille = function
| VRAI | Predicat _ -> 1
| NON a | X a | G a | F a -> 1 + taille a
| ET (a, b) | OU (a, b) | U (a, b) -> 1 + taille a + taille b
关于一个和两个参数的情况并不像您希望的那么简洁,但是我认为不可能做得更好。您不能在构造函数上使用通配符(_
)。
另一个想法是在辅助函数中捕获“提取参数”模式:
let args = function
| VRAI | Predicat _ -> []
| NON a | X a | G a | F a -> [a]
| ET (a, b) | OU (a, b) | U (a, b) -> [a; b]
然后您可以写:
let rec taille f = List.fold_left (fun a x -> a + taille x) 1 (args f)
或者,没有中间列表:
let fold_args f1 f2 c =
let rec g = function
| VRAI | Predicat _ -> c
| NON a | X a | G a | F a -> f1 (g a)
| ET (a, b) | OU (a, b) | U (a, b) -> f2 (g a) (g b)
in
g
let taille = fold_args (fun x -> 1 + x) (fun x y -> 1 + x + y) 1
答案 1 :(得分:0)
在您的情况下,我将像这样重构类型formule
:
type infix = ET | OU | U
type prefix = NON | X | G | F
type formule =
| VRAI
| Predicat of char
| Infix of formule * infix * formule
| Prefix of prefix * formule
我不知道您正在使用的域,但是我想这是带有前缀和中缀运算符的某种语言。
然后您可以像这样编写taille
函数:
let rec taille = function
| VRAI | Predicat _ -> 1
| Prefix (_, a) -> 1 + taille a
| Infix (a, _, b) -> 1 + taille a + taille b
现在,您的类型更加精细,您可能会发现对新类型有意义的新功能。