In F#, we can declare a polymorphic value
> let a = [];; val a : 'a list
However, if we make it mutable, fsharpi complains with value restriction error
> let mutable a = [];; let mutable a = [];; ------------^ /Users/kseo/stdin(1,13): error FS0030: Value restriction. The value 'a' has been inferred to have generic type val mutable a : '_a list Either define 'a' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation. > let a = [];; val a : 'a list
This looks unreasonable at first! But let’s see what happens if we get rid of this restriction.
let mutable a = [] let f x = a <- (x :: a) f(1);; f(true);; f(“Hello World”);;
The type of function f
is ‘a -> unit. Hence f(1), f(true) and f(“Hello World”) type check. However, a
ends up having three different types [“Hello World”; true; 1]
. Oops! So, the type system of F# has a rule called value restriction to prevent this kind of bad behaviour.
In fact, all ML family languages have value restriction. See Notes on SML97’s Value Restriction for further information.