Specs
Type parameters are opaque
Normally, you can't do anything with a type parameter t
unless it would work for every type.
The above example doesn't work even though there is an == function for nats.
all-same can't be defined that way unless == worked for every type (which it doesn't).
This can be fixed by declaring all-same to use the equal spec.
The above example works because the equal spec predeclares that an == function should exist.
Then the caller of foo is responsible for providing that function.
The caller knows the actual type substituted for t (in this case nat)
and looks for a concrete == function.
In this case it looks for == bool(a nat, b nat)
and finds it in the standard library.
Specs are written after function parameters.
Multiple specs can be separated by commas as in t data, t equal .
For a multi-line function signature, specs are written after the do keyword.
Defining specs
A spec declaration has a list of signatures in an indented block.
This defines an area spec and uses it to define prism-volume.
That allows that function to call area on the type parameter.
The syntax for spec signatures is the same as for union methods, but there is no implicit first parameter.
Spec inheritance
A spec can inherit from other specs.
In the above example, shape inherits from area,
so it includes both area and perimeter signatures.
Special specs
The special spec data doesn't include any signatures.
Instead, it is only satisfied for data types.
(See Mutability.)
shared is the corresponding spec for shared types.
There are also two special specs global and unsafe that don't have a type argument or any signatures.
See Global side effects and Unsafe code.
Auto functions and specs
Even auto functions can use specs.
Below, == needs to use the equal spec so that the (automatic) body
can call == on value.
Multiple type parameters
Specs can have any number of type parameters.
(Even 0 which is useful for avoiding circular imports. See Modules.)
The example above used the to spec, which takes the return type and parameter type of a
to function as type parameters.
Methods and specs
Methods (and method implementations) can not declare specs.