![](/img/trans.png)
[英]What is the difference between `let .. in do` and `<-` notation in Haskell Monads?
[英]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.