在函数中使用`let ... in`

时间:2014-06-15 20:50:53

标签: haskell

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

3 个答案:

答案 0 :(得分:4)

let ... in ...允许多个声明介于letin之间,然后是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,这并不是那么有趣,所以它不会从计算的前面部分得到关注。