The type system will ensure that the types of the values a function is given match the type signature of the function.
That is, if you have a function that takes an integer as input, such as
fun double n = 2 * n
(* this function has type: int -> int *)
Then n
will always be an integer. It will not be possible to call the function with anything but an integer; it will give a type error.
If you have a polymorphic function, such as
fun pair n = (n, n)
(* this function has type: 'a -> 'a * 'a *)
Then you cannot know what type the input is at runtime. All types of input will be treated the same.
You can, however, always restrict a polymorphic function to only work on a given type, by making the type explicit when defining the function:
fun pairInt (n : int) = (n, n)
(* this function has type: int -> int * int *)
You can see the difference between pair
and pairInt
by comparing what you get from calling pair 5
to pairInt 5
, and pair "foo"
to pairInt "foo"
.
If you have an int option
, as is the case if you try to convert an string
to a int
using Int.fromString
, you can extract the int
in several ways. For how to do this, I refer you to the question "In smlnj how do you convert “string option” to “string”?".