gpt4 book ai didi

F#/OCaml : How to avoid duplicate pattern match?

转载 作者:行者123 更新时间:2023-12-04 22:24:25 26 4
gpt4 key购买 nike

看看这个 F#/OCaml 代码:

type AllPossible =
| A of int
| B of int*int
| ...
| Z of ...

let foo x =
....
match x with
| A(value) | B(value,_) -> (* LINE 1 *)
(* do something with the first (or only, in the case of A) value *)
...
(* now do something that is different in the case of B *)
let possibleData =
match x with
| A(a) -> bar1(a)
| B(a,b) -> bar2(a+b)
| _ -> raise Exception (* the problem - read below *)
(* work with possibleData *)
...
| Z -> ...

那么问题是什么?
在函数 foo 中,我们对一个大的类型列表进行模式匹配。
某些类型共享功能 - 例如他们有共同的
工作要做,所以我们在上面的第 1 行中使用“|A | B ->”。
我们读取唯一的整数(在 A 的情况下),或第一个整数
(在 B 的情况下)并用它做一些事情。

接下来,我们想做一些完全不同的事情,这取决于
关于我们是在 A 还是 B 上工作(即调用 bar1 或 bar2)。
我们现在必须再次进行模式匹配,这就是问题所在:在这个
嵌套模式匹配,除非我们添加“catchAll”规则(即“_”),
编译器提示我们缺少案例 - 即它没有
考虑到这里只有 A 和 B 可以发生。

但是如果我们添加 catchAll 规则,那么我们就会遇到一个更糟糕的问题:
如果在某个时候我们在 LINE1 的列表中添加更多类型
(即在 '|A | B ->' 行中......那么编译器将无济于事
我们在嵌套匹配中 - '_' 将捕获它们,并且会出现错误
在运行时检测到。最重要的权力之一
模式匹配 - 即在编译时检测此类错误 - 丢失。

有没有更好的方法来编写这种代码,而无需
以两个独立的方式重复 A 和 B 之间共享的任何工作
A 和 B 的规则? (或将 A 和 B 共同工作放在一个函数中
仅为 A 和 B 之间的“本地代码共享”而创建?)

编辑 :请注意,在这种情况下,有人可能会争辩说 F# 编译器的行为有问题 -
它应该能够检测到除了 A 和 B 之外不需要匹配
在嵌套匹配中。

最佳答案

如果数据类型是一成不变的 - 我也更喜欢本地函数。

否则,在 OCaml 中,您还可以享受开放(又名多态)变体:

type t = [`A | `B | `C]
let f = function
| (`A | `B as x) ->
let s = match x with `A -> "a" | `B -> "b" in
print_endline s
| `C -> print_endline "ugh"

关于F#/OCaml : How to avoid duplicate pattern match?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6857139/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com