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
示例中,为什么let
的in
放在in result
上?
【问题讨论】:
它还能放在哪里? @KevinMeredith 这是一个多行的let-in
语句。 let-in
语法允许您定义一个或多个可在in
后面的表达式中使用的中间值。这就像where
语句一样,您可以在其中定义任意数量的本地表达式。 let-in 和 where 之间有一些微妙之处,即 let ... in ...
可以在子表达式中使用。你不能把上面写成(x * 2 where x = 2) + 3
,Haskell 不允许。
【参考方案1】:
let ... in ...
允许 多个 声明出现在 let
和 in
之间,然后在 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的主要内容,如果未能解决你的问题,请参考以下文章