Reputation: 191159
I have this code in Haskell.
import Data.List
main = do
putStrLn $ "\nVerify if Exists in a String"
let wordlist = ["monad", "monoid", "Galois", "ghc", "SPJ"]
let tweet = "This is an example tweet talking about SPJ interviewing with Galois"
print $ map (flip isInfixOf tweet) wordlist
Without the let
, I have this error message: 10_things.hs:16:14: parse error on input ‘=’
.
This is another code that works fine.
import Data.List
wordlist = ["monad", "monoid", "Galois", "ghc", "SPJ"]
tweet = "This is an example tweet talking about SPJ interviewing with Galois"
main = do
putStrLn $ "\nVerify if Exists in a String"
print $ map (flip isInfixOf tweet) wordlist
In this case, I have error parse error (possibly incorrect indentation or mismatched brackets)
with let.
My question is when and when not to use let
in Haskell?
Upvotes: 5
Views: 3027
Reputation: 615
do notation is for monads. I am guessing you are unclear about monads.
let used inside do notation is basically binding. the do notation translates to this form
do {let x = expression; restofit} ==> let x = expression in do {restofit}
For instance this
do
line1 <- getLine -- executes an action
line2 <- getLine -- executes an action
let joined = line1 ++ line2 -- pure calculation; no action is executed
return joined
This translates to
let joined = line1 ++ line2 in line1 <-getLine >> line2 <- getLine
Upvotes: -1
Reputation: 68172
Haskell has two ways to introduce names: let
and where
.
You use let
whenever you could have a normal expression. This can come up in two places: if you're defining a normal value and if you're inside do-notation. In the first case, you would use let ... in
to introduce a name just within a single expression:
myFoo = let x = 10 ^ 10 in x + x
Inside do-notation, you do not need an in
; instead, the let
takes up a line just like a normal "statement" in do-notation. This is what your first example has:
main = do
let x = something
...
The other way to introduce names is with where
clauses, which go outside of expression. The top-level of your program—where you define all the globally visible names in your module—is in a where
block, which is why you just write name = expression
without a let
. This happens because your module implicitly has
module Main where
on top even if you didn't write it yourself.
You can also write where
blocks of your own in different scopes, which also let you define names without let
:
foo x = ...
where helperA = something
helperB = something
Upvotes: 10
Reputation: 18199
Declarations/equations need to be inside either a let
or a where
block. The reason you don't need let
at the top level of a module, is that it counts as a where
block all by itself, started by its module
declaration. A module which doesn't contain an explicit module
header gets an implicit
module Main (main) where
at the beginning.
By the way, an indented let
block can contain more than one declaration: you don't need the second let
in your code as long as the equations line up vertically.
Upvotes: 12