有let
的原因是什么在 do
堵塞。
-- codeblock A
main = do
let a = 0
let f a = a + 1
let b = f 0
print (a,b)
-- codeblock B
main = do
a = 0
f a = a + 1
b = f 0
print (a,b)
假设所有
let
没有 in
必须跟=
(这是真的?)编译器应该能够暗示
let
来自 =
和预处理/脱糖codeblock B
至codeblock A
使用
let
在这种情况下似乎是不必要的,就像你可以写 codeblock C
但选择写codeblock D
-- codeblock C
main = do
print (a,b)
a = 0
f a = a + 1
b = f 0
-- codeblock D
main = do
print (a,b)
function a = 0
function f a = a + 1
function b = f 0
为了澄清我的假设不包括
let
紧随其后的是 in
应该保持不变。-- codeblock E
main = do
a = 0
f a = a + 1
b = f 0
c = let d = 1
e = 1
in d + e
print (a,b,c)
最佳答案
我不知道为什么这样做,但这是我可以想象的一个原因:它允许您指定应按顺序建立哪些绑定(bind),以及同时建立哪些绑定(bind),这在阴影的情况下可能很重要。
例如,假设您的建议得到实现,然后考虑:
foo :: [Int]
foo = do
x <- return [1]
y = 0:x
x = [1..5]
y
有两种合理的方法可以脱糖:
foo1 :: [Int]
foo1 = do
x <- return [1]
let y = 0:x
let x = [1..5]
y
foo2 :: [Int]
foo2 = do
x <- return [1]
let y = 0:x
x = [1..5]
y
foo1
计算结果为 [0,1]
, 和 foo2
至[0,1,2,3,4,5]
.当然,这是一种奇怪的代码编写方式,但事实上 let
必须明确表示您的意图没有歧义。正如 chi 的评论中所述,阴影不是您可能需要明确说明您的
let
的唯一原因。绑定(bind)是分组的:一个函数定义可能需要多个方程,以匹配多个参数模式。
关于haskell - 为什么在 do block 中需要 let 关键字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40647332/