Haskell 中的“让”和“进入”是啥意思?
Posted
技术标签:
【中文标题】Haskell 中的“让”和“进入”是啥意思?【英文标题】:What do 'let' and 'in' mean in Haskell?Haskell 中的“让”和“进入”是什么意思? 【发布时间】:2020-12-27 22:20:07 【问题描述】:我觉得这个看似简单而重要的东西对我来说完全是神秘的。 “让”表达是什么意思?我试过google,结果都是我不懂的概念。
这是我在讲座中编写的一些代码。它识别给定的字符串是否是回文。我也不太明白 return 关键字在哪里。是“在”吗?这个功能的范围是什么?我很茫然。
module Main where
isPalindrome :: Text -> Bool
isPalindrome text1
= let
list = toString text1
backwards = reverse list
in list == backwards
当它出现在“let”之后时,“in”是什么意思?
我是学 C# 的,对函数式编程一窍不通。
谢谢。
【问题讨论】:
let
创建一个或多个名称绑定,您需要另一个表达式,这些绑定在范围内并且可以使用..
是的,在您的代码 sn-p 中,'return' 值(实际上是计算的表达式)是 'in' 块的内容:list == backwards
。 let
表示表达式中的术语(列表,向后)具有您可以在 let
中查找的绑定。
这相当于list == backwards where list = toString text1...
,但您可能会看到任何一种格式(let/in
vs where
),具体取决于作者希望如何阅读代码
Haskel 没有“返回关键字”
Haskell let
表达式 let x1 = e1; …; xn = en in e
可以在 C# 中使用包含一系列 var
声明和 return
语句的 lambda 表达式来模拟,该语句会立即被调用:(() => var x1 = e1; …; var xn = en; return e; )()
。变量在表达式e
的范围内,整个事情的计算结果为e
。一个细微的区别是,在 Haskell 中,any 变量可以相互引用,而在 C# 中,每个变量只能引用定义在 之前 的变量。
【参考方案1】:
let
-block 允许您创建局部变量。一般形式是
let
var1 = expression
var2 = another expression
var3 = stuff
in
result expression
无论result expression
是什么结果,但您可以在result expression
内部使用var1
、var2
和var3
(以及在expression
、another expression
和stuff
内部) )。您可以将let
和in
视为您要定义的一堆局部变量的括号。是的,in
之后的内容就是您要返回的内容。
【讨论】:
【参考方案2】:让我们看一个使用 IO
的示例,因为这更像是您习惯使用的命令式语言:
main :: IO ()
main = do
let n = 37
print n
应该很容易吧? let n = 37
引入了一个名为 n
的局部变量,并赋予其值 37
。然后可以像使用任何全局定义一样使用该变量。这与C#中的var n = 37;
或int n = 37;
基本相同。
但是 Haskell 不是命令式语言,所以看起来像“做这个,然后做那个”实际上只是纯粹功能性的语法糖。在这个例子中,do
块去糖看起来非常相似:
main = let n = 37
in print n
区别和优势在于,变量不是在某个时间点按原样引入的,这意味着您需要注意执行操作的确切顺序,但是而是将其引入具体的作用域。 let
-bound 变量的范围包括 in
之后的所有内容,还包括 let
-block 本身中的所有内容,这意味着您也可以拥有
main = let m = n + 2
n = 37
in print m
(注意“反向控制流”)甚至递归定义
main = let l = 1 : m
m = 2 : l
in print $ take 15 l
(后者将打印[1,2,1,2,1,2,1,2,1,2,1,2,1]
)
【讨论】:
谢谢,这有帮助。问题是我不太清楚自己不知道的东西,所以很难开始。这澄清了一些事情!以上是关于Haskell 中的“让”和“进入”是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章