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 x
s 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.