繁体   English   中英

在Haskell中,使用和不使用let有什么区别?

[英]In Haskell, what is the difference between using and not using let?

有人告诉我Haskell没有变量,但是有绑定。 现在这意味着什么,我一直想知道编写这些绑定时有什么区别,就像这样:

x = 5

let x = 5

这里有什么区别?

还有一个后续问题:我是否通过执行此操作来创建变量? 如果x不是变量,那是什么?

唯一真正的区别是它们的发生位置。

-- At top (file) level or in "where" blocks, omit "let".
x = 5

f1 y = x + y
  where
    x = 5

-- Inside expressions or do-blocks, "let" is required.
f2 y = let x = 5
       in x + y

f3 y = do someAction
          let x = 5
          return (x + y)

在所有情况下, x是一个变量。 但是,您不能更改(变异)变量的值。

在GHCi提示符下,似乎您更改了变量的值,但不能更改。 您只能创建具有相同名称的新变量,而旧变量仍然存在。

Prelude> let x = 3
Prelude> let f y = x + y
Prelude> let x = 10
Prelude> f 1
4

如果您确实更改了x的值,则f 1将为11。

Haskell有变量,但是我们说它们是绑定的,而不是赋值的 这些概念极为相似,但是它们是否支持多重分配却有所不同-Haskell不支持。

do let x = 1
   let x = 2
   print x     -- prints "2"

当我们说不时,我们的意思是所有变量都是静态绑定的。 这意味着,只要有对变量的引用,您就可以在代码中查找并找到它所引用的一个绑定。

以Python为例,它确实具有多个分配。

def f(a):
    x = 1          # first assignment
    x = 2          # second assignment

    for i in a:
        x = i      # third assignment
        print x 

    print x

在上面的示例中,在三个位置分配了x 当在最后一行引用x时,我们可以从第二个赋值中获取2 ,或者可以从循环中的赋值中获取a的值之一。 第三次分配是否发生取决于a是否为空。

因此,让我们看一下Haskell中的类似代码:

f a = do let x = 1                    -- first binding
         let x = 2                    -- second binding
         for_ a $ \i -> do let x = i  -- third binding
                           print x
         print x

此输出的最后一行将始终为“ 2”,因为在代码中的该点,第二个绑定是x在该范围内接收到的最里面的绑定。 如果我们要引入另一个更紧密的绑定,则可以更改它:

f a = do let x = 1                    -- first binding
         let x = 2                    -- second binding
         for_ a $ \i -> do let x = i  -- third binding
                           print x
         let x = head a               -- fourth binding
         print x

但是,我们不能做的是介绍含糊不清 ,其结合东西指。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM