The following examples are very closely derived from
Edinburgh LCF, showing a rough overview of the syntax and features of ML. The character at the start of a line denotes user input, and lines without it are system responses showing the value and its inferred type. Note that this section is not meant to act as a comprehensive set of language features that ML contains, rather a subset to give a sense for the language. Refer to
Edinburgh LCF for a more rigorous definition. Expressions are evaluated by typing them followed by and a return character. The identifier holds the result of the last-evaluated expression.
Bindings are introduced with , and multiple bindings can be made simultaneously by joining them with the keyword, or by constructing pairs (which has a product type, explored in a later example) on the right hand side, which is
pattern-matched to the left: Functions are defined with . Function application is higher precedent than mathematical operators, so means . Functions defined with multiple parameters are
curried, so passing one parameter into the function will return a function that will accept the second, and so on. Recursive functions require so the function name is in scope within its body. The syntax for an anonymous function is similar to lambda calculus, with for lambda and separating arguments from the expression: Lists use semicolons between elements. and are built-in functions that return the head and tail; is
cons (prepend); is append. Functions like are polymorphic—ML uses generic type variables (, , etc.) to express this:
Mutable variables are declared with and updated with . The keyword belongs to the if-then-loop construct, which iterates every time the conditional fails: Tokens are ML's string type, delimited by ; double backticks create token lists. A common use for tokens was identifying failures with , a keyword used to raise exceptions with an explicit token, and is used to trap it: Abstract types are declared with , which creates a new type and defines the functions that work with it, while keeping the internal structure (the concrete type it's built from) hidden. Abstract recursive types are declared with , which allows the type to be used in its own definition. There is a similar keyword , which is used for more basic
type aliasing. Here is a recursive abstract type that defines a
binary tree with some basic operations: Inside the operation definitions (the block), the type's name can be prepended with to
box values in the type and to unbox values. The characters and in type definitions signify
sum types (tagged unions) and
product types (tuples), respectively, with having a higher precedence. ML on LCF provided several helper functions used in the example above. Operating on sum types , the functions and inject values into the left or right side of a sum type. extracts from left injections (fails if given a right injection), and extracts from right injections (fails if given a left injection). For product types , the extraction functions are and , which extract the first and second components of a pair. Product types are constructed using the comma infix operator. In the tree example above, takes a single parameter that is a pair pattern , which destructures the pair into its three components. ==See also==