let foo = bar in ...
simply defines foo
to be the exact same thing as bar
within the context of ...
; you could simply use textual substitution to replace all uses of foo
in ...
with (bar)
and get the exact same result.
where
clauses are similar to let...in
expressions, but go at the end of a function clause, instead of being an expression. For instance,
foo x
| p1 = ... y ...
| p2 = ... y ...
where
y = ...
There is no way to rewrite this with let...in
without changing the guards into if...then...else
s. Often, where
clauses are used over let...in
clauses purely for reasons of style.
The bind operator is something different entirely. It's used in do
notation to "extract" a value from a monadic computation. That is, if foo
has the type m a
, then after x <- foo
, x
has the type a
. All the other "binding" forms just define names, but <-
is used for binding a computation's result to a name from within a monad. <-
can only be used inside a do
block, so it's exclusively used to build up a larger computation in the same monad as the action you're binding the result of.
let foo = bar
in do
notation is just a convenience; you can rewrite:
do let foo = bar
...
as
let foo = bar
in do ...
but that gets messy when you have a lot of such bindings, as the do
blocks get nested deeper and deeper.
I don't know what the advice you mentioned is talking about; you can define multiple variables in a let...in
block just fine, and
let foo = ...
bar ...
in ...
is more idiomatic than
let foo = ...
in let bar = ...
in ...
a <- f b
tolet a = f b
(or vice versa) wouldn't break your code. That is assuming you're actually usinga
afterwards. – Paresthesiaf b
has a non-monadic typea <- f b
will simply not compile. There's no refactoring you can do to make it compile (unless you count stuffing areturn
in there to be refactoring...). Iff b
does have a monadic type,let a = f b
will causea
to have the same type. This will almost certainly break the code usinga
. – Paresthesia<-
s inside a do-block, their respective right operands must be in the same monad. But that has nothing to do withlet
. – Paresthesia