在Haskell中,使用和不使用LET之间有什么区别

  • 本文关键字:之间 区别 LET Haskell haskell
  • 更新时间 :
  • 英文 :


有人告诉我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提示中,似乎您更改了变量的值,但不能。您只能创建具有相同名称的新变量,旧变量仍然存在。

前奏令x = 3前奏令f y = x   y前奏令x = 10前奏F 14

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

haskell具有变量,但我们说它们是 bond 而不是分配的。这些是非常相似的概念,但是它们是否支持多重分配 -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

但是,我们永远无法做的是歧义 binting 某物是指的。

最新更新