【问题标题】:Haskell's newtypes in Typescript?Haskell 在 Typescript 中的新类型?
【发布时间】:2019-08-04 21:54:38
【问题描述】:

在 Haskell 中,我们可以声明允许我们隐藏对底层数据类型的访问的新类型。这允许我们通过不暴露诸如底层数组之类的东西在模块中创建更安全的 API(使库的用户不可能越界)。

Typescript 中有没有类似于 newtypes 的东西?

【问题讨论】:

标签: typescript haskell types


【解决方案1】:

作为对此的跟进,还有另一种方法可以引入类似于 newtypes 的东西。

您可以执行以下操作:

type Seed = number & {readonly Seed: unique symbol}

const createSeed = randomNumberBetween0And1() as Seed

const doSomethingWithSeed = (s: Seed) => {...}

doSomethingWithSeed(1) // will complain
doSomethingWithSeed(createSeed()) // Will not complain

【讨论】:

  • 这看起来很有趣,但有点吓人——你能解释一下它是如何工作的吗?它使用了一些我不熟悉的 TypeScript 功能。
【解决方案2】:

FWIW 一个具有单个私有字段的类或多或少是相同的,所以它不像关键字是严格需要的。

还要注意,Haskell 中的newtype 并不是真正的封装,尽管您可以这样使用它——它是为了使相同的结构表示具有不同的类型,防止意外误用并允许基于类型的广告通过类型类的 hoc 多态性。 Haskell 的 data 工作方式几乎相同,除了实现细节之外,newtype A = A Xdata A = A X 之间的区别更多的是哲学而非技术。

【讨论】:

  • 称那些“实施细节”是低估了情况。 newtype 构造函数的模式匹配和直接从语义差异得出的数据构造函数之间存在真正的操作差异。新类型构造函数上的大小写匹配是无操作的。数据构造函数的大小写匹配会强制求值,即使该类型只有一个构造函数。这种差异对于在关心它们的情况下获得正确的评估属性是巨大的。
  • @Carl 在 Haskell 的某些情况下,这是一个相关的细节。这与关于如何在 Typescript 中做同样事情的讨论并不真正相关。
  • 我想这是最好的方法。太糟糕了,这一切都必须隐藏在一个类后面,所以在用 Javascript 进行函数式编程时,你必须混合模块和类。我宁愿完全跳过那里的课程。
  • “具有单个私有字段的类或多或少是相同的东西” - 这是掩盖新类型最常见的用途是用于数字(例如,用于单位或不同的 ID 类型)和使用结构放弃了值语义和算术运算符,这是一个非常大的缺点。
  • @Timmmm 如果你做得对,你确实有值语义,而且缺少中缀运算符在最坏的情况下是一个小麻烦。尤其是因为在许多情况下(例如 ID),您通常都不想要​​它们中的大多数。
猜你喜欢
  • 2022-01-24
  • 1970-01-01
  • 2020-05-23
  • 2016-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多