线性类型如何阻止 "duplicate" 的这种实现?

How can linear types prevent such implementation of "duplicate"?

我最近读到 the post on Tweag.IO 关于线性类型是表达仅(恰好)使用一次的参数的有用工具。他们给出了以下示例:

dup :: a ⊸ (a,a)
dup x = (x,x)

现在,也许我误解了这个想法,但为什么不能通过以下方式规避:

dup' :: a ⊸ (a,a)
dup' x = (y,y)
  where
    y = x

文章特别提到参数。这是否也扩展到函数中的所有绑定?

我觉得这篇文章几乎没有解释底层语义——只是举例说明了如何使用这种技术。公平地说,这可能是一种适合博客的格式 post。

您可以将 x ⊸ y 视为 1 x -> y 的同义词,后者是一个常规箭头,其域为 1 x,表示变量 a :: 1 x 仅使用一次。通过类型推断,在您的第二个示例中,y 获得推断类型 1 a,因为 y = xx :: 1 a。这扩展到所有自然数和无穷大。此外,常规箭头 x -> y 可以读作 ω x -> y,其中 ω 是无穷大。

您链接的 paper 给出了正确的语义。参见第 3.1 节,图。 2 - let 对应的打字规则。标准打字判断 x : T 泛化为 x :_{q} T (即 q 应该是下标)。在现有的 Haskell 类型语义中,术语使用其类型进行注释。在提议的类型系统扩展中,一个术语用它的类型和它的多重性来注释。

但是,请注意,在那篇论文中,let 构造始终包含 let 绑定变量的显式类型签名。使用那篇论文的语法,你的第二个程序(实际上,大多数 Haskell 程序!)在语法上什至都不是有效的。但是我声称(没有证据)不难看出如何将这样的类型系统概括为更让人联想到当前 Haskell 类型系统的类型系统。请参阅关于 GHC 的提案 trac 以了解有关其外观的更多详细信息。