我不明白这三种语法之间的区别:
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...elses ,就无法重写它。通常,出于风格原因,where从句在从句上使用。let...in
绑定运算符完全不同。它用于do表示法从一元计算中“提取”一个值。也就是说,如果foo有类型m a,那么之后x <- foo,x就有类型a。所有其他“绑定”形式只是定义名称,但<-用于将计算结果绑定到 monad 中的名称。<-只能在do块内使用,因此它专门用于在与您绑定结果的操作相同的 monad 中建立更大的计算。
let foo = bardo记号只是为了方便;你可以重写:
do let foo = bar
...
作为
let foo = bar
in do ...
但是当你有很多这样的绑定时,这会变得一团糟,因为do块嵌套得越来越深。
我不知道你提到的建议在说什么;您可以在一个块中定义多个变量let...in就好了,并且
let foo = ...
bar ...
in ...
比
let foo = ...
in let bar = ...
in ...