For ordinary local function bindings, and variable bindings with let
in general, you have to use in
after all functions/variables have been defined:
let bar j = j < 5
in bar i
A let
without in
can be used within a do
block only, in which case the variable is defined for the rest of the do
block:
blah = do
let bar j = j < 5
assert $ not $ bar 5
pure $ bar 5
However, that can only be used where it is valid to use do
. Otherwise, use in
.
A where
clause can also be attached to a definition, in lieu of let
:
foo i = bar i
where bar j = j < 5
This use of where
is unrelated to its role in template
syntax.
Note that where
, while it is nicer for some cases, is pretty restrictive about where (sorry) it can be used, whereas (sorry again) let
/in
works anywhere an expression is allowed:
foo i =
let bar j = j < 5
in bar (let q = 2 in i + q)
See daml docs on let and this discussion of when to use let or where.