Learn You a Haskell显示shortLines
函数:
shortLinesOnly :: String -> String
shortLinesOnly input =
let allLines = lines input
shortLines = filter (\line -> length line < 10) allLines
result = unlines shortLines
in result
通过这个有用的post,我觉得以下let ... in
是正确的:
> (let x = 2 in x*2) + 3
7
但是,在上面的shortLinesOnly
示例中,为什么let
&#39; in
位于in result
?
答案 0 :(得分:4)
let ... in ...
允许多个声明介于let
和in
之间,然后是in
之后的单个表达式整个let ... in ...
表达式的最终值。所有声明都在表达式的范围内(以及每个声明的主体)。
所以你给出的两个例子都是有效的 - 简单的例子只是做一个声明(x = 2
)而更复杂的例子是定义三件事(allLines = ...
等)。
答案 1 :(得分:1)
当您看到let A in B
时,您可以将B
视为声明的值。在命令式语言中,您可以将其写为A; return B
。
我们也可以将代码编写为
shortLinesOnly :: String -> String
shortLinesOnly input =
let allLines = lines input
shortLines = filter (\line -> length line < 10) allLines
in unlines shortLines
您还可以将let A in B
视为与B where A
几乎相同。
答案 2 :(得分:1)
如果Haskell是一种过程语言,你会像这样编写函数体:
allLines = lines input
shortLines = filter (\line -> length line < 10) allLines
return unlines shortLines
将此直接转换为功能样式将导致
let allLines = lines input
shortLines = filter (\line -> length line < 10) allLines
in unlines shortLines
那么,为什么要为结果而烦恼呢?为了更好的可读性。 let
语句通常代表“定义要在主表达式中使用的一些参数”。但是这里unline shortLines
不是函数的“主表达式” - 它只是计算的最后阶段。为了防止它成为焦点,增加了另一个阶段 - 即result = unline shotLines
。现在“主要表达式”是result
,这并不是那么有趣,所以它不会从计算的前面部分得到关注。