我不明白这三种语法之间的区别:
where a = f (b)
do a <- f (b)
do let a = f (b)
a <- f(b)
尽管这与其他两个不同,但我确实理解,在大多数情况下,我尝试了所有三个工作。此外,我在网上某处读到,每个块您应该尝试与一个 let 绑定相处,以便“惯用”。但我似乎从来没有管理过。
我如何决定使用什么?
我不明白这三种语法之间的区别:
where a = f (b)
do a <- f (b)
do let a = f (b)
a <- f(b)
尽管这与其他两个不同,但我确实理解,在大多数情况下,我尝试了所有三个工作。此外,我在网上某处读到,每个块您应该尝试与一个 let 绑定相处,以便“惯用”。但我似乎从来没有管理过。
我如何决定使用什么?
let foo = bar in ...
简单地定义为与;的上下文中foo
完全相同的事物 您可以简单地使用文本替换来替换in的所有用法并获得完全相同的结果。bar
...
foo
...
(bar)
where
子句类似于let...in
表达式,但位于函数子句的末尾,而不是表达式。例如,
foo x
| p1 = ... y ...
| p2 = ... y ...
where
y = ...
let...in
如果不将守卫更改为if...then...else
s ,就无法重写它。通常,出于风格原因,where
从句在从句上使用。let...in
绑定运算符完全不同。它用于do
表示法从一元计算中“提取”一个值。也就是说,如果foo
有类型m a
,那么之后x <- foo
,x
就有类型a
。所有其他“绑定”形式只是定义名称,但<-
用于将计算结果绑定到 monad 中的名称。<-
只能在do
块内使用,因此它专门用于在与您绑定结果的操作相同的 monad 中建立更大的计算。
let foo = bar
do
记号只是为了方便;你可以重写:
do let foo = bar
...
作为
let foo = bar
in do ...
但是当你有很多这样的绑定时,这会变得一团糟,因为do
块嵌套得越来越深。
我不知道你提到的建议在说什么;您可以在一个块中定义多个变量let...in
就好了,并且
let foo = ...
bar ...
in ...
比
let foo = ...
in let bar = ...
in ...