I feel like this seemingly simple and essential thing is completely cryptic to me. What does 'let' expression mean? I have tried to google, but the results are full of concepts that I don't understand.
Here is some code I wrote during a lecture. It identifies if a given string is a palindrome. I don't quite understand where the return keyword is either. Is it the 'in'? What is the scope of this function? I am at a loss.
module Main where
isPalindrome :: Text -> Bool
isPalindrome text1
= let
list = toString text1
backwards = reverse list
in list == backwards
What does 'in' mean, when it comes after 'let'?
I come from learning C#, and functional programming is unknown to me.
Thank you.
A let
-block allows you to create local variables. The general form is
let
var1 = expression
var2 = another expression
var3 = stuff
in
result expression
The result of this is whatever result expression
is, but you can use var1
, var2
and var3
inside result expression
(and inside expression
, another expression
, and stuff
as well). You can think of let
and in
as being brackets around the bunch of local variables you want to define. And yes, the thing after in
is what you're returning.
Let's look at an example using IO
, as that's more like the imperative languages you're used to:
main :: IO ()
main = do
let n = 37
print n
Should be easy enough, right? let n = 37
introduces a local variable called n
, giving it the value 37
. That variable can then be used like any global definition. This is basically the same as var n = 37;
or int n = 37;
in C#.
But Haskell is not an imperative language, so what looks like “do this, then do that” is actually just syntactic sugar for something purely functional. In this example, the do
block desugars to something looking very similar:
main = let n = 37
in print n
The difference, and advantage, is that the variable is not introduced at some point in time as it were, which means you need to be careful about the exact order in which you do stuff, but rather it is introduced into a concrete scope . The scope of a let
-bound variable includes everything that comes after the in
, but also anything in the let
-block itself, meaning you could also have
main = let m = n + 2
n = 37
in print m
(note the “reverse control flow”) or even recursive definitions
main = let l = 1 : m
m = 2 : l
in print $ take 15 l
(the latter will print [1,2,1,2,1,2,1,2,1,2,1,2,1]
)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.