在 Haskell 中,可变性是否总是必须反映在类型系统中?

发布于 2025-01-09 03:24:43 字数 194 浏览 4 评论 0原文

我是 Haskell 的新手,所以如果这个问题很愚蠢,请原谅。

想象一下,我们有两个绑定到名称 xy 的数据结构。

x 是可变的。

y 不是。

作为一个问题或原则,x 是否一定具有与 y 不同的类型?

I'm new to Haskell, so please forgive if this question is dumb.

Imagine that we have two data structures bound to the names x and y.

x is mutable.

y is not.

As a matter or principle, does x necessarily have a different type than y?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

执笔绘流年 2025-01-16 03:24:43

简短的回答:是的。

在 Haskell 中,所有变量在技术上都是不可变的。与 JavaScript 不同,一旦你在 Haskell 中定义了一个新变量并将其绑定到一个初始值:

let x = expression1 in body1

这就是它永远的值。在 body1 中使用 x 的任何地方,其值都保证是 expression1 的(固定)值。 (嗯,从技术上讲,您可以在 body1 中定义一个具有相同名称的全新不可变变量 x,然后在 body 中定义一些 x可能会引用那个新变量,但那是完全不同的事情。)

Haskell 确实有可变的数据结构。我们通过创建一个新的可变结构并将其绑定到一个不可变变量来使用它们:

do ...
   xref <- newIORef (15 :: Int) 
   ...

这里,xref本身的值不是整数 15。相反,xref 被分配了一个不可变的、不可显示的值,该值标识一个“容器”,其内容当前为 15。要使用这个容器,我们需要显式地从中取出值,我们可以将其分配给不可变的变量:

  value_of_x_right_now <- readIORef xref

并显式地放置值进入it:

  writeIORef xref (value_of_x_right_now + 15)

显然,关于这些值,以及通常需要通过 IO 或其他 monad 中的 monadic 操作访问它们的方式,还有很多可说的。

但是,即使抛开这一点,应该清楚的是,整数 15 和“内容初始化为整数 15 的容器”是具有必然不同类型的对象。在本例中,类型分别为 IntIORef Int

因此,数据结构的可变性必然会反映在类型级别,仅仅因为 Haskell 中的可变性是通过这些类型的“容器”实现的,并且值的类型与值的类型不同。包含该值的容器。

Short answer: yes.

In Haskell, all variables are technically immutable. Unlike in, say, JavaScript, once you've defined a new variable in Haskell and bound it to an initial value:

let x = expression1 in body1

that's its value forever. Everywhere that x is used in body1, its value is guaranteed to be the (fixed) value of expression1. (Well, technically, you can define a brand new immutable variable x with the same name in body1 and then some of the xs in body might refer to that new variable, but that's a whole different matter.)

Haskell does have mutable data structures. We use them by creating a new mutable structure and binding that to an immutable variable:

do ...
   xref <- newIORef (15 :: Int) 
   ...

Here, the value of xref itself is not the integer 15. Rather, xref is assigned an immutable, undisplayable value that identifies a "container" whose contents are currently 15. To use this container, we need to explicitly pull values out of it, which we can assign to immutable variables:

  value_of_x_right_now <- readIORef xref

and explicitly put values into it:

  writeIORef xref (value_of_x_right_now + 15)

There's obviously much more that can be said about these values, and the way in which they generally need to be accessed via monadic operations in IO or another monad.

But, even setting that aside, it should be clear that the integer 15 and a "container whose contents are initialized to the integer 15" are objects with necessarily different types. In this case, the types are Int and IORef Int respectively.

So, the mutability of data structures will necessarily be reflected at the type level, simply by virtue of the fact that mutability in Haskell is implemented via these sorts of "containers", and the type of a value is not the same as the type of a container containing that value.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文