[英]What programming languages have something like Haskell’s `newtype`
Haskell编程语言有一个newtypes
的概念:如果我写newtype Foo = Foo (Bar)
,那么创建一个与Bar
同构的新类型Foo
,即两者之间存在双射转换。 这个结构的属性是:
还有哪些编程语言提供此功能?
当与记录访问器/构造器一起使用时,一个示例似乎是C中的单值结构。 当与强制转换一起使用时,无效候选者将是C中的单值结构,因为编译器不会检查强制转换,或者Java中具有单个成员的对象,因为它们不会共享相同的表示。
相关问题: F#是否具有Haskell的“新类型”? (不) D是否有'newtype'? (不再)。
不过, Frege有这个,不像Haskell那样没有额外的关键字。 相反,只有一个组件的每种产品类型都是新类型。
例:
data Age = Age Int
此外,所有具有标称类型且允许根据另一个定义类型的languga都应该具有此功能。 例如Oberon,Modula-2或ADA。 所以之后
type age = integer; {* kindly forgive syntax errors *}
一个人不能混淆年龄和其他数量。
Mercury是一种纯逻辑编程语言,类型系统类似于Haskell。
Mercury中的评估是严格的而不是懒惰的,因此Mercury等同于newtype
和data
之间没有语义差异。 因此,恰好只有一个构造函数只有一个参数的任何类型都与该参数的类型相同,但仍被视为相同的类型; 有效的“newtype”是Mercury中的透明优化。 例:
:- type wrapped
---> foo(int)
; bar(string).
:- type wrapper ---> wrapper(wrapped).
:- type synonym == wrapped.
的表示wrapper
将等同于的wrapped
,但是一种独特的类型,而不是synonym
这简直是该类型的另一个名称wrapped
。
Mercury在其表示中使用带标记的指针。 1严格并且被允许对不同类型有不同的表示,水星通常会尽可能地消除拳击。 例如
“newtype”优化实际上只是该一般概念的一个特定应用。 “包装器”类型不需要在已经保持“包装”类型的上方分配任何存储器单元。 由于它需要零标签位,因此它也可以适应“包装”类型的引用中的任何标签。 因此,对“包装”类型的整个引用可以内联到对包装器类型的引用中,这最终在运行时无法区分。
1此处的详细信息可能仅适用于低级别C编译等级。 Mercury也可以编译为“高级”C或Java。 在Java中显然没有任何小问题(尽管我知道“newtype”优化仍然适用),而我对高级C级别的实现细节不太熟悉。
Rust总是允许你创建单字段类型,但是使用最近稳定的repr(transparent)
属性,您现在可以确信创建的类型将具有精确的数据布局作为包装类型,甚至可以跨FFI等。
#[repr(transparent)]
pub struct FooWrapper(Foo);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.