从构造函数中进行泛型提取 [英] Generic extraction from a constructor

查看:101
本文介绍了从构造函数中进行泛型提取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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 xfun (Blah whatever) -> ...,您不再需要解包功能.

  • You may use clever patterns instead of a function : by using let (Blah whatever) = f x, or fun (Blah whatever) -> ..., you don't need an unpacking function anymore.

或者您可以写

type blah = (blah_tag * whatever) and blah_tag = Blah

这样,您没有总和类型,而是产品类型(您写(Blah, whatever)),而peel只是snd.对于每个blahfoo等,您仍然具有不同(不兼容)的类型,但是具有统一的访问接口.

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.

这篇关于从构造函数中进行泛型提取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆