Lazy values
-- | the first element, or what the default comes to: the default is-- | computed only for an empty list-- | >>> firstOr ~(List.length (List.range 0 1000000)) [5, 6]-- | 5firstOr : ~Int -> List Int -> IntfirstOr d [] = dfirstOr d (x :: _) = xheff computes by value: an argument is computed before the call. ~
puts that off.
~A and ~e
~Ais the typeLazy A: anAnot computed yet.~edelayse: aLazyofe’s type, computed only where it is forced.
Which of the two ~e is, its e says: where e is a type, ~e is
that type’s Lazy; otherwise e is delayed. Types and values share
their syntax, so both are written the same way:
-- | >>> force (later Int 5)-- | 5later : (a : Type) -> a -> ~alater a x = ~xLazy takes a Type, so there is no Lazy Type: a type cannot be
delayed.
A Lazy can be anywhere a type can: a field of a data type or a
record, a function’s argument or result.
data Cell = MkCell ~Int StringSpacing
~ is written close to what it delays, as - is to what it negates
(Numbers): ~ right before a name, a
number, a string, a rune, ( or [, and not right after an operand,
is this ~. So:
| Written | Means |
|---|---|
~x, ~(f x), ~[1, 2], ~~x | delayed |
f ~x | f applied to ~x |
a ~ b, a~b, ~ x | the operator ~, if one is defined |
~ reaches as far as an argument does: ~f x is (~f) x; delay a
call as ~(f x).
Forcing
force : {a : Type} -> Lazy a -> a computes the value. And where an
a is wanted and a Lazy a is given, it is forced without writing
force: the prelude has a coercion, Coe (Lazy a) a
(Coercions).
square : Int -> Intsquare n = n * n
-- | >>> squareOf ~7-- | 49squareOf : ~Int -> IntsquareOf l = square lAn operator is a theory’s (Operators), whose instance
is looked for at the type given, so l * 2 looks for one of ~Int:
write force l * 2.
A Lazy is computed the first time it is forced, and its value is
kept: forced again, it is not computed again. A Lazy handed to many
places, or forced in a loop, is computed once.
What is never forced is never computed: ~abandon is a value like any
other until something forces it.
Only ~e delays
A delay is never put in for you. Where a ~Int is wanted, an Int is
an error, as is a call that gives one:
seven : ~Intseven = ~(3 + 4) -- not `seven = 3 + 4`A Lazy’s tag is the language’s own: a Lazy is made by ~e, and
taken apart by forcing it.