Error: This expression has type t/1 but an expression was expected of type
t/2
Hint: The type t has been defined multiple times in this toplevel
session. Some toplevel values still refer to old versions of this
type. Did you try to redefine them?
In general the error messages have been continuously improving in recent years. #include<stdio.h>
#define DX 0.0001
typedef double (*function)(double);
typedef double (*closure_body)(void*, double);
struct deriv_env { function f; };
struct closure { void* env; closure_body body; };
#define CALL(c, x) ((c)->body((c)->env, (x)))
double deriv_body(void *env, double x) {
function f = (deriv_env *)env->f;
return (f(x + DX) - f(x)) / DX;
}
void deriv(function f, struct closure *out) {
out->env = (void *)f;
out->body = deriv_body;
}
double cube(double x) { return x * x * x; }
int main(void) {
struct closure cube_deriv;
deriv(&cube, &cube_deriv);
printf("%f\n", CALL(&cube_deriv, 2.));
printf("%f\n", CALL(&cube_deriv, 3.));
printf("%f\n", CALL(&cube_deriv, 4.));
return 0;
}
`type 'a t = Cons of 'a * 'a t | Tail` is defining a type with a constructor `Cons` with two arguments and a constructor `Tail` with zero argument. You write values of type `'a t` as `Cons (a, b)` and `Tail`.
`type 'a u = (::) of 'a * 'a u | []` is defining a type with a constructor `(::)` with two arguments and a constructor `[]` with zero argument. You build values of type `'a u` as `(::) (a, b)` and `[]`.
The rest comes from the special syntax support in OCaml for the `(::)` and `[]` names. Namely, `a :: b` is parsed as `(::) (a, b)`, and `[a; b; ...; z]` is parsed as `a :: b :: ... :: z :: []`, and hence as `(::) (a, (::) (b, (::) (..., (::) (z, []))))`.