什么是有原因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)
Run Code Online (Sandbox Code Playgroud)
假设所有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
Run Code Online (Sandbox Code Playgroud)
澄清我的假设并不包括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)
Run Code Online (Sandbox Code Playgroud)
ama*_*loy 15
我不知道为什么会这样做,但这是我可以想象的一个原因:它允许你指定哪些绑定应该顺序建立,哪些同时,哪些在阴影的情况下可能很重要.
例如,假设您的建议已实施,然后考虑:
foo :: [Int]
foo = do
x <- return [1]
y = 0:x
x = [1..5]
y
Run Code Online (Sandbox Code Playgroud)
有两种合理的方法可以解决这个问题:
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
Run Code Online (Sandbox Code Playgroud)
foo1计算结果为[0,1],并foo2到[0,1,2,3,4,5].当然,这是编写代码的一种奇怪的方式,但是let需要明确的这一事实意味着对于您的意图没有任何歧义.
正如chi的评论中所指出的,阴影并不是你可能需要明确关于如何对let绑定进行分组的唯一原因:函数定义可能需要多个方程,以匹配多个参数模式.
支持 的一个论点let是,它在do块中更加突出,否则这些块可能会被各种类似一元赋值的运算符填充(想想某些填充了 中定义lens的运算符的东西)。
do
p1.x += delta -- (+=) is a custom operator
p2.y -= delta -- (-=) is a custom operator
let delta' = delta*delta
p3 .= Point delta' delta' -- (.=) is a custom operator
Run Code Online (Sandbox Code Playgroud)
在这里delta',由于let.
| 归档时间: |
|
| 查看次数: |
531 次 |
| 最近记录: |