let in

Posted 牧羊龟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了let in相关的知识,希望对你有一定的参考价值。

如下

cylinder :: ( RealFloat a ) => a -> a -> a
cylinder r h =
  let sideArea = 2 * pi * r * h
      topArea = pi * r ^ 2
  in sideArea + 2 * topArea
  • let in表达式非常类似于where语法结构
  • let in表达式用于在任何地方绑定变量,并且它们本身就是表达式,但它们是局部的,所以不能用在御林军之间
  • let in表达式可以使用模式
  • let in的形式是 let in
  • 在let部分中定义的变量或函数可以在in部分中访问

因为let in是表达式,所以几乎可以在任何地方使用,如下

4 * (let a = 9 in a + 1) + 2
42

[let square x = x * x in (square 3, square 5, square 7)]
[(9, 25, 49)]

如果想在一行上定义多个变量,需要用分号分隔它们,如下

(let a = 100; b = 200; c = 300 in a * b * c, let foo = "Hey"; bar = "there!" in foo ++ bar)

let in表达式使用模式,如下

(let (a, b, c) = (1, 2, 3) in a * b *c) * 100

在内涵列表中使用let in表达式,如下

calcBmis :: (RealFloat a) => [(a, a)] -> [a]
calcBmis xs = [bmi | (w, h) <- xs, let bmi = w / h ^ 2, bmi >= 25.0]
  • 内涵列表中的let像一个谓词,但它不过滤元素,只是定义变量
  • 内涵列表中的let表达式定义的变量可以在输出函数(|之前的部分)以及let之后的所有谓词和部分中看到
  • 内涵列表中的let in表达式的in部分省略了,因为定义变量的可见性是预先知道的
  • 但是可以在谓词中使用let in表达式,并且定义的变量只在该谓词中可见

将 `let ... in` 与函数一起使用

【中文标题】将 `let ... in` 与函数一起使用【英文标题】:Using `let ... in` with Function 【发布时间】: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 不允许。 【参考方案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,它并没有那么有趣,所以它并没有把重点放在前面的计算部分。

【讨论】:

以上是关于let in的主要内容,如果未能解决你的问题,请参考以下文章

在 OCaml 中的 let 命令(即 let _ = ... in)中使用下划线通配符有啥副作用吗?

链接“let”语句时最好使用“and”或“in”?

for(let i in data){}

let in

prog vs. let in LISP 性能差异

为啥我不能在 Swift 中使用 let in 协议?