【问题标题】:Using `let ... in` with Function将 `let ... in` 与函数一起使用
【发布时间】:2014-08-05 16:57:03
【问题描述】:

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 示例中,为什么letin 放在in result 上?

【问题讨论】:

  • 它还能放在哪里?
  • @KevinMeredith 这是一个多行的let-in 语句。 let-in 语法允许您定义一个或多个可在in 后面的表达式中使用的中间值。这就像where 语句一样,您可以在其中定义任意数量的本地表达式。 let-in 和 where 之间有一些微妙之处,即 let ... in ... 可以在子表达式中使用。你不能把上面写成(x * 2 where x = 2) + 3,Haskell 不允许。

标签: haskell


【解决方案1】:

let ... in ... 允许 多个 声明出现在 letin 之间,然后在 in 之后的单个表达式是整个 let ... in ... 的最终值表达。所有声明都在表达式的范围内(以及每个声明的主体)。

所以你给出的两个例子都是有效的——简单的例子只是做一个声明(x = 2),而更复杂的例子是定义三件事(allLines = ...等)。

【讨论】:

    【解决方案2】:

    当您看到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

    【讨论】:

      【解决方案3】:

      如果 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,它并没有那么有趣,所以它并没有把重点放在前面的计算部分。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-01-03
        • 2010-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多