什么编程语言有类似Haskell的`newtype`

Joa*_*ner 17 haskell programming-languages functional-programming newtype

Haskell编程语言有一个概念newtypes:如果我写newtype Foo = Foo (Bar),那么Foo创建一个同构的新类型Bar,即两者之间存在双射转换.这个结构的属性是:

  • 这两种类型是完全独立的(即编译器不允许您使用另一种类型,而不使用显式转换).
  • 他们有相同的代表性.特别是,转换函数的运行时成本为零,并在堆上返回"相同的对象".
  • 转换只能在这些类型之间进行,并且不能被误用,即保留类型安全性.

还有哪些编程语言提供此功能?

当与记录访问器/构造器一起使用时,一个示例似乎是C中的单值结构.当与强制转换一起使用时,无效候选者将是C中的单值结构,因为编译器不会检查强制转换,或者Java中具有单个成员的对象,因为它们不会共享相同的表示.

相关问题:F#是否具有Haskell的"新类型"?(不)D是否有'newtype'?(不再).

Ing*_*ngo 11

不过,Frege有这个,不像Haskell那样没有额外的关键字.相反,只有一个组件的每种产品类型都是新类型.

例:

data Age = Age Int
Run Code Online (Sandbox Code Playgroud)

此外,所有具有标称类型且允许根据另一个定义类型的languga都应该具有此功能.例如Oberon,Modula-2或ADA.所以之后

type age = integer;      {* kindly forgive syntax errors *}
Run Code Online (Sandbox Code Playgroud)

一个人不能混淆年龄和其他数量.


Ben*_*mes 8

我相信Scala的价值等级满足这些条件.

例如:

case class Kelvin(k: Double) extends AnyVal
Run Code Online (Sandbox Code Playgroud)

编辑:实际上,我不确定转换在所有情况下都是零开销.本文档描述了必须在堆上分配对象的一些情况,因此我假设在这些情况下,从对象访问底层值会有一些运行时开销.


Fre*_*Foo 7

去吧:

如果我们宣布

type MyInt int

var i int
var j MyInt
Run Code Online (Sandbox Code Playgroud)

然后我有类型int和j类型MyInt.变量i和j具有不同的静态类型,虽然它们具有相同的基础类型,但如果没有转换,它们就不能相互分配.

"相同的基础类型"意味着a的内存中的MyInt表示正好是a的表示int.MyInt将a 传递给期望a的函数int是编译时错误.复合类型也是如此,例如之后

type foo struct { x int }
type bar struct { x int }
Run Code Online (Sandbox Code Playgroud)

你不能传递bar给期望foo(测试)的函数.


Lok*_*hor 5

Rust 始终允许您创建单字段类型,但通过最近稳定的repr(transparent)属性,您现在可以确信创建的类型将具有与包装类型完全相同的数据布局,甚至跨 FFI 等。

#[repr(transparent)]
pub struct FooWrapper(Foo);
Run Code Online (Sandbox Code Playgroud)