在F#和OCaml中,我最终写了很多代码
type C = Blah of Whatever
let d = Blah (createWhatever ()) // so d is type C
...
let x = match d with | Blah b -> b
Run Code Online (Sandbox Code Playgroud)
我想要的是这个
...
let x = peel d
Run Code Online (Sandbox Code Playgroud)
剥离适用于任何构造函数/鉴别器.
当然,我不是唯一一个对此感到恼火的人.
编辑:很好的答案,但我没有代表对他们投票.这种情况怎么样?
member self.Length = match self with | L lab -> lab.Length
Run Code Online (Sandbox Code Playgroud)
不可能安全地做到这一点:如果peel是一个函数,它的类型是什么?它不能打字,因此不能成为语言中的"好人".
你可以 :
使用反射(在F#中)或类型破坏函数(在OCaml中它是Obj模块),但你会得到一些不安全的东西,不精确的类型,所以它相当丑陋,"使用风险自负"
使用元编程为您生成peel每种类型的不同版本.例如,使用type-conv OCaml工具,您可能隐式type blah = Blah of something定义了一个函数peel_blah,并type foo = Foo of something定义了peel_foo.
更好的解决方案是......首先不需要这样的解决方案peel.我看到两种可能性:
您可以使用聪明的模式而不是函数:通过使用let (Blah whatever) = f x,或者fun (Blah whatever) -> ...,您不再需要解包功能.
或者你可以,而不是写type blah = Blah of what,写
type blah = (blah_tag * whatever) and blah_tag = Blah
这样,你就没有总和类型而是产品类型(你写的(Blah, whatever)),而你peel就是这样snd.你还有一个不同(不兼容)键入每个blah,foo等等,但一个统一的访问接口.