14

我不明白这三种语法之间的区别:

  • where a = f (b)
  • do a <- f (b)
  • do let a = f (b)

a <- f(b)尽管这与其他两个不同,但我确实理解,在大多数情况下,我尝试了所有三个工作。此外,我在网上某处读到,每个块您应该尝试与一个 let 绑定相处,以便“惯用”。但我似乎从来没有管理过。

我如何决定使用什么?

4

1 回答 1

26

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 <- foox就有类型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 ...
于 2012-02-13T00:37:07.317 回答