问题描述
最近我一直在做一些OCaml编程来学习语言,并更多地熟悉函数式编程。最近,我开始认为我希望能够扩展现有类型(内置或我自己的内置类型),例如: 类型bexp =
而bexp * bexp
|或者是bexp * bexp
| XOR的bexp * bexp
|不是bexp ;;
现在我们假设我想为这种类型添加一个Nop变体,但仅限于用于新类型 - 有点像继承。嘿,这些应该是代数数据类型,对吧?那么为什么不这样:
type nbexp = bexp | Nop nbexp ;;
...但这是无效的OCaml,它给出了语法错误。基本上,我想要做的是说,我想要nbexp包括一切bexp包括,并添加一个Nop。我想这是不可能的,因为,例如,如果您使用And构造函数,则无法确定它是否是bexp类型或nbexp类型。 (我认为构造函数Nop采用nbexp也可能会有问题。)
那么在OCaml中有什么方法可以做到这一点?而且,这是Haskell中可行的事情(可能带有类型类型)吗?
有趣的解决方案是使用多态变体:
类型bexp =
[`和bexp * bexp
| `或者bexp * bexp
| `bexp * bexp
的XOR `不是bexp] ;;
type nbexp = [bexp | `Nop of nbexp] ;;
请注意,多态变体比普通变体更棘手,但允许扩展类型。 b
$ b
表达式评估的一个有趣的例子,带有扩展,使用多态变量可以在ocaml源的测试目录中找到,请参阅
I've been doing some OCaml programming lately to learn the language and to get more acquainted with functional programming. Recently, I've started to think that I'd like to be able to extend an existing type (either built in-or one of my own), for example:
type bexp =
And of bexp * bexp
| Or of bexp * bexp
| Xor of bexp * bexp
| Not of bexp;;
Now let's say I want to add a Nop variant to this type, but only for use in a new type - kind of like inheritance. Hey, these are supposed to be Algebraic data types, right? So why not something like:
type nbexp = bexp | Nop nbexp ;;
...but this isn't valid OCaml, it gives a syntax error. Basically, what I'm trying to do is say that I want nbexp to include everything bexp includes and also add a Nop to that. I suppose this isn't possible because, if for example you used the And constructor there would be no way to determine if it was a bexp type or a nbexp type. ( I think the constructor Nop taking a nbexp may also be problematic.)
So is there any way to do something like this in OCaml? And, is this the sort of thing that's doable in Haskell (with typeclasses, perhaps)?
An interesting solution is to use polymorphic variant:
type bexp =
[ `And of bexp * bexp
| `Or of bexp * bexp
| `Xor of bexp * bexp
| `Not of bexp ];;
type nbexp = [ bexp | `Nop of nbexp ];;
Note that polymorphic variants are trickier than normal ones, but allow extension of type.
An interesting example of expression evaluation, with extension, using polymorphic variant can be found in a test directories of the ocaml source, see the svn
这篇关于扩展OCaml中的现有类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!