Standard ML
errors
Case #1
fun foo x y = x + y;
foo 5 -4;
Explanation
We use - and not ~ for negation. Actually, ML reads this as (foo 5) - 4, so that’s why this error is there
Case 2
fun foo x y = x + y;
fun bar (x, y) = x * y;
foo 2 bar(1, 2);
Explanation
Curried function application is greedy - ML reads this as 3 arguments for foo, and you can’t pass bar as the second argument to foo - that’s a type error
Case 3
fun foo [] = 0
| foo x::xs = x;
Explanation
Parentheses - needs to be (x::xs). ML considers this to be a triple of x, ::, xs and complains about being given a tuple and not a list
Case 4
case "0" of
"0" => 0
| "1" => case 0 of _ => 1
| "2" => 2
| _ => 3;
Explanation
Parentheses - the inner case needs to be (case 0 of _ => 1). Also notice that the error is a type error, but it’s not to be handled as a type error. ML reads the "2" and later _ case as belonging to the second case and not the first one
Case 5
fun foo (a: {x: int, y: int}) = x;
Explanation
x is not a field. It’s part of the type of a. The correct way is #x a
Case 6
type A = {x: int, y: int};
fun foo a = #s1 a;
Explanation
ML cannot do type inferrence to deduce the entire type of a, so it results in an error. ML cannot do partial type inferrence
Case 7
Math.pow(2.0, 3.0) - 1;
Explanation
Type mismatch. pow returns real
Case 8
fun f x = Math.sqrt x;
if (f 9.0 = f 9.0) then 1 else 0;
Explanation
real is a not a polymorphic equality type - cannot compare reals. This is a type error because in ML types that are able to be compared using = are denoted by ''a, and real is 'a but not ''a
Case 9
fun f g x = if g = g then g x else 0;
Explanation
Ditto. g is a function (actually, 'a -> int) and functions are not polymorphic equality types. However, since it is first used in a comparison and only then as a function, the error will be reported in the function application and not in the equality. It actually concludes it cannot be a function, rather than concluding it cannot be a polyEqual type
Case 10
fun f (a:{s: int, r: int}) = {s: (#s a), r: (#r a)};
Explanation
: denotes type, we need to use = in the returned expression to denote a value. Another common error: {(#s a), (#r a)}
Case 11
fun f a:{s: int, r: int} = {s = (#s a), r = (#r a)};
Explanation
The type here in the constraint binds to the function - f, rather than to a, like it may seem. This apparently should not cause an issue, because that is the actual type we are returning, however, it does leave a without a precise type constraint and this is a problem because like before, ML cannot do partial type inferrence and it cannot conclude the exact type for a, just some of its fields
Case 12
local
fun rec (a, _, 0) = a
| rec (a, b, n) = rec (a + b, a, n - 1)
in
fun fib n = rec (1, 1, n)
end;
Explanation
rec is a keyword…
Case 13
val x = (1 = 1) and (2 = 2);
Explanation
andalso is logical AND and not and. Also, orelse and not or
Case 14
val x = "Andrey\n";
fun f () = print ("My name is " ^ x);
val x = "Maroon\n";
f ();
Explanation
Functions freeze the values they refer to, and do not get updated when the identifier is reused
Case 15
Math.pow (2.0, 3.0);
floor it = 8;
Explanation
Terribly annoying floating-point arithmetic error. When doing integer arithmetic, implement manually with a recursive function.
Case 16
fun a () = b () and fun b () = a ()
Explanation
We don’t repeat the fun keyword after and. Ditto for val, datatype