Home > Net >  In Haskell, does mutability always have to be reflected in type system?
In Haskell, does mutability always have to be reflected in type system?

Time:02-24

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?

CodePudding user response:

There's no such thing as a mutable variable, so the question does not arise. Perhaps you could be more specific about the scenario you are imagining. Using the shortcut "mutable variable" for it has not conveyed whatever you intended to convey.

CodePudding user response:

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.

  • Related