问题描述
在F#和OCaml中,我最终编写了很多代码,例如
In F# and OCaml I wind up writing a lot of code like
type C = Blah of Whatever
let d = Blah (createWhatever ()) // so d is type C
...
let x = match d with | Blah b -> b
我想要的是
...
let x = peel d
在哪里剥皮适用于任何构造函数/判别器.
当然,我不是唯一一个对此感到恼火的人.
好的答案,但我没有代表对它们进行投票.这种情况怎么样?
Where peel would work for any constructor/discriminator.
Surely I'm not the only one annoyed by this.
edit:Good answers, but I don't have the rep to vote on them.How about this situation?
member self.Length = match self with | L lab -> lab.Length
推荐答案
不可能安全地做到这一点:如果peel
是一个函数,它的类型是什么?它不能被键入,因此不能成为该语言中的好人".
It is not possible to do that safely : if peel
was a function, what would be its type ? It cannot be typed and therefore cannot be a "good guy" in the language.
您可以:
-
使用反射(在F#中)或类型破坏函数(在OCaml中是
Obj
模块),但是使用不精确的类型会导致一些不安全的情况,因此它相当丑陋,使用风险自负" "
use reflection (in F#) or type-breaking functions (in OCaml it's the
Obj
module), but you will get something unsafe with an imprecise type, so it's rather ugly and "use at your own risk"
使用元编程为每种类型生成不同版本的peel
.例如,使用 type-conv OCaml工具,您可能具有type blah = Blah of something
隐式定义函数peel_blah
,而type foo = Foo of something
定义peel_foo
.
use metaprogramming to generate different versions of peel
at each type for you. For example, using the type-conv OCaml tool, you may have type blah = Blah of something
define a function peel_blah
implicitly, and type foo = Foo of something
define peel_foo
.
恕我直言,更好的解决方案是……首先不需要这样的peel
.我看到两种可能性:
The better solution imho is... not to need such a peel
in the first place. I see two possibilities:
-
您可以使用巧妙的模式而不是功能:通过使用
let (Blah whatever) = f x
或fun (Blah whatever) -> ...
,您不再需要解包功能.
You may use clever patterns instead of a function : by using
let (Blah whatever) = f x
, orfun (Blah whatever) -> ...
, you don't need an unpacking function anymore.
或者您可以写
type blah = (blah_tag * whatever) and blah_tag = Blah
这样,您没有总和类型,而是产品类型(您写(Blah, whatever)
),而peel
只是snd
.对于每个blah
,foo
等,您仍然具有不同(不兼容)的类型,但是具有统一的访问接口.
This way, you don't have a sum type but a product type (you write (Blah, whatever)
), and your peel
is just snd
. You still have a different (incompatible) type for each blah
, foo
etc, but a uniform access interface.
这篇关于从构造函数中进行泛型提取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!