Basic Types
int, real, bool, string, char
Every value in SML has a type — a label that classifies what kind of value it is. Def 5.1.3 (notes p.78) says types classify program objects.
The four basic types you will use constantly:
int— integers:~3,0,42,1000000. (Note:~is SML's negation sign, not-.)real— floating-point numbers:3.14,~2.5,1.0e10.bool— booleans:true,false.string— sequences of characters:"hello","".
You can build compound types using type constructors:
- char — single characters: #"a".
- Tuples: int * string is the type of pairs like (3, "hi").
- Lists: int list is the type of lists of integers like [1, 2, 3].
- Functions: int -> int is the type of functions from int to int.
SML is statically typed: every expression's type is determined at compile time, and mismatches cause errors before the program runs. You usually do not have to write down types — SML's type inference figures them out for you. For example, fn x => x + 1 is inferred as int -> int because + works on ints.
A char in SML is a single character, written #"a", #"Z", #"5". To turn a string into a char list (and back), SML provides explode and implode:
explode "Hello" = [#"H", #"e", #"l", #"l", #"o"]
implode [#"H", #"e", #"l", #"l", #"o"] = "Hello"
A string is sugar for a list of chars: type string is char list. So "abc" is sugar for [#"a", #"b", #"c"].
Palindrome example — a string reads the same forwards and backwards:
fun palindrome s =
let val cs = explode s
val rs = rev cs
in cs = rs end;
palindrome "racecar";
(* val it = true : bool *)
palindrome "hello";
(* val it = false : bool *)
The key insight: s = rev s iff s is a palindrome. This generalises to any list, not just char lists.
3.14 have?(3, "hi", true)?explode "cat" return?