Haskell 中的“let”和“in”是什么意思?

Cma*_*ram 9 haskell functional-programming let

我觉得这个看似简单而本质的东西对我来说完全是神秘的。“让”表达是什么意思?我试过谷歌,但结果充满了我不明白的概念。

这是我在讲座中编写的一些代码。它标识给定的字符串是否是回文。我也不太明白 return 关键字在哪里。是“在”吗?这个功能的范围是什么?我很茫然。

module Main where

isPalindrome :: Text -> Bool
isPalindrome text1 
  = let
    list = toString text1
    backwards = reverse list
    in list == backwards
Run Code Online (Sandbox Code Playgroud)

当它出现在“让”之后时,“in”是什么意思?

我是学 C# 的,对函数式编程一窍不通。

谢谢你。

Mat*_*hid 13

一个let-阻塞允许你创建局部变量。一般形式是

let
  var1 = expression
  var2 = another expression
  var3 = stuff
in
  result expression
Run Code Online (Sandbox Code Playgroud)

这样做的结果是什么result expression,但您可以使用var1,var2var3inside result expression(以及 inside expressionanother expressionstuff以及)。您可以将letin视为要定义的一堆局部变量周围的括号。是的,in接下来就是你要返回的东西。


lef*_*out 10

让我们看一个使用 的示例IO,因为它更像是您习惯的命令式语言:

main :: IO ()
main = do
   let n = 37
   print n
Run Code Online (Sandbox Code Playgroud)

应该很容易吧?let n = 37引入一个名为 的局部变量n,赋予它值37。然后可以像使用任何全局定义一样使用该变量。这与C# 中的var n = 37;或基本相同int n = 37;

但是 Haskell不是命令式语言,所以看起来“做这个,然后做那个”实际上只是纯粹功能性的语法糖。在这个例子中,do块 desugar 看起来非常相似:

main = let n = 37
       in print n
Run Code Online (Sandbox Code Playgroud)

不同之处和优势在于变量不是在某个时间点引入的,这意味着您需要注意执行操作的确切顺序,而是将其引入到具体的作用域中let-bound 变量的范围包括 之后的所有内容in,但也包括let-block 本身中的任何内容,这意味着您还可以拥有

main = let m = n + 2
           n = 37
       in print m
Run Code Online (Sandbox Code Playgroud)

(注意“反向控制流”)甚至递归定义

main = let l = 1 : m
           m = 2 : l
       in print $ take 15 l
Run Code Online (Sandbox Code Playgroud)

(后者将打印[1,2,1,2,1,2,1,2,1,2,1,2,1]

  • 谢谢,这有帮助。问题是我不太了解自己不知道的事情,所以很难上手。这稍微澄清了一些事情! (2认同)