在 Haskell 中,我们什么时候使用 in 和 let ?

2024-04-19

在下面的代码中,我可以将最后一个短语放在in在前。它会改变什么吗?

另一个问题:如果我决定把in最后一个短语前面需要缩进吗?

我尝试不缩进并拥抱抱怨

do {...} 中的最后一个生成器必须是表达式

import Data.Char
groupsOf _ [] = []
groupsOf n xs = 
    take n xs : groupsOf n ( tail xs )

problem_8 x = maximum . map product . groupsOf 5 $ x
main = do t <- readFile "p8.log" 
          let digits = map digitToInt $concat $ lines t
          print $ problem_8 digits

Edit

好吧,所以人们似乎不明白我在说什么。让我重新表述一下: 鉴于上述上下文,以下两个是否相同?

1.

let digits = map digitToInt $concat $ lines t
print $ problem_8 digits

2.

let digits = map digitToInt $concat $ lines t
in print $ problem_8 digits

关于声明的绑定范围的另一个问题let: 我读here http://www.haskell.org/tutorial/patterns.html that:

where条款。

有时,在多个受保护的方程上设置绑定范围很方便,这需要一个 where 子句:

f x y  |  y>z           =  ...
       |  y==z          =  ...
       |  y<z           =  ...
     where z = x*x

请注意,这不能使用 let 表达式来完成,let 表达式的范围仅限于表达式它所包含的.

我的问题:所以,可变数字对于最后一个打印短语不应该是可见的。我在这里错过了什么吗?


简短回答: Use let没有in在 do 块的主体中​​,以及在|在列表理解中。在其他地方,使用let ... in ....


关键词let在 Haskell 中以三种方式使用。

  1. 第一种形式是let 表达式.

    let variable = expression in expression
    

    这可以在任何允许表达式的地方使用,例如

    > (let x = 2 in x*2) + 3
    7
    
  2. 第二个是一个let 语句。该形式仅在 do 表示法内部使用,不使用in.

    do statements
       let variable = expression
       statements
    
  3. 第三个与第二个类似,用在列表推导式内部。再说一遍,不in.

    > [(x, y) | x <- [1..3], let y = 2*x]
    [(1,2),(2,4),(3,6)]
    

    这种形式绑定一个变量,该变量在后续生成器和之前的表达式中|.


您在这里感到困惑的原因是表达式(正确类型的)可以用作 do 块中的语句,并且let .. in ..只是一个表达。

由于 haskell 的缩进规则,比前一行缩进得更远的行意味着它是前一行的延续,所以这

do let x = 42 in
     foo

被解析为

do (let x = 42 in foo)

如果没有缩进,您会收到解析错误:

do (let x = 42 in)
   foo

总之,永远不要使用in在列表理解或 do 块中。这是不必要且令人困惑的,因为这些结构已经有自己的形式let.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Haskell 中,我们什么时候使用 in 和 let ? 的相关文章

  • Haskell:单词,取消单词分隔符

    有什么办法可以提供分隔符words and unwords在haskell中 使其类似于python中的split和join 另请查看友好的包裹split 它提供了一个模块Data List Split http hackage haske
  • Haskell-Stack:构建期间出现访问冲突错误

    过去几天我一直在尝试使用堆栈构建我的 Haskell 项目 但遇到了访问冲突错误 据我了解 我有最新的堆栈版本和 GHC 这一切最初都是有效的 直到我将一个库添加到我的 cabal 文件中 我现在已经将其删除 但错误仍然出现 我也恢复到我的
  • php从函数返回中访问数组值

    愚蠢的php问题 为什么我不能这样做 echo Auth getFullUser country 相反你必须这样做 user Auth getFullUser echo user country 不幸的是 语法不允许这样做 AFAIK 曾经
  • 为什么Data.Hashmap中没有mapKeys?

    我想使用诸如mapKeys to map仅限按键 即有一个功能mapKeys in Data Map 但没有类似物Data Hashmap 此外 在Data Hashmap我没有发现任何有关操作按键的信息 是否只有不完整之处Data Has
  • 由相同数据类型的不同构造函数共享的 Haskell 记录访问器

    关于 Haskell 记录的基本问题 如果我定义这个数据类型 data Pet Dog name String Cat name String deriving Show 以下作品 main do let d Dog name Spot c
  • 尝试以特殊行为渲染 Threepenny-gui 中的字段

    我想要做的是设置字段 当它们处于焦点时显示详细信息 而当它们不处于焦点时显示摘要 例如 A 当它失去焦点 变得模糊 时 我将值保存在 状态 映射中 然后将该值更改为旧值的函数 即汇总值 b 当它获得焦点时 我用我在地图中保存的旧值替换摘要值
  • 用户状态(秒差距)

    我正在使用秒差距解析一个表达式 并且我想使用秒差距中的用户状态来跟踪这些表达式中的变量 不幸的是我真的不知道该怎么做 给出以下代码 import Data Set as Set inp x y z data Var V String var
  • Javascript var 提升问题

    我有一个非常简单的 Javascript 函数 它可以访问 MS SQL 服务器并返回一些记录 有一个单元格 我只想在它唯一时才显示在顶部表格行中 我相信我的问题是 var 提升 因为我在 while 循环中分配的变量不起作用 因为该值不是
  • jQuery text() 的替代方案包括元素之间的空格?

    我在容器中有一些任意的正文文本 我不控制它 所以我不知道它的结构 但像这样的事情 div h1 Heading h1 p A paragraph or two p ul li item 1 li li item 2 li ul div 这只
  • 主函数抱怨返回非 IO monad

    import Debug Trace main do trace Main function parses and returns 0 return 这会引发错误 app hs 3 1 Couldn t match expected typ
  • Angularjs如何从外部访问范围数据

    我有这个轮询器函数 每 10000 毫秒轮询一次数据 这很好 但是我需要能够从外部访问变量 以便我可以使用splice功能 服务代码 use strict service to get data for analytics page ang
  • 通过引用调用原型函数时,类失去“this”范围

    谁能向我解释为什么 b 返回未定义以及如何解决这个问题 当我通过引用调用原型函数时 为什么 this 范围会丢失 MyClass function test this test test MyClass prototype myfunc f
  • Haskell 错误:“非详尽模式”

    所以我有这个功能 当我尝试像这样使用它时 合并排序列表 1 1 1 1 它给了我一个错误 1 1 例外 SortFunctions hs 86 1 91 89 非详尽 函数 mergeSortedLists 中的模式 85 mergeSor
  • 理解 Haskell 中的矩阵转置函数

    这个矩阵转置函数有效 但我试图理解它的逐步执行 但我不明白 transpose a gt a transpose transpose x map head x transpose map tail x with transpose 1 2
  • 为什么 Haskell 类型签名声明有多个箭头?

    抱歉 这句话措辞不好 但很难描述 我想我会跳到这个例子 add Integer gt Integer gt Integer add x y x y 为什么 Integer gt Integer gt Integer 代替 Integer I
  • 枚举类型的命名空间 - 最佳实践

    通常 需要同时使用多种枚举类型 有时 人们会发生名字冲突 我想到了两种解决方案 使用命名空间 或使用 更大的 枚举元素名称 尽管如此 命名空间解决方案有两种可能的实现 带有嵌套枚举的虚拟类 或完整的命名空间 我正在寻找所有三种方法的优缺点
  • Haskell 有反向模式自动微分的工作实现吗?

    我见过的 Haskell 中最相关的实现是前向模式http hackage haskell org packages archive fad 1 0 doc html Numeric FAD html http hackage haskel
  • 使用 jQuery 加载脚本时保持范围

    假设我有一个包含以下内容的文件 test js var test something 然后我有一个主要脚本需要加载 test js 以获取测试变量 显然这有效 ajax dataType script cache true url test
  • 如何制作Applicative的固定长度向量实例?

    最近了解了推广 决定尝试写向量 LANGUAGE DataKinds GADTs KindSignatures module Vector where data Nat Next Nat Zero data Vector Nat gt gt
  • Foldl 是否比其严格的表亲 Foldl' 更好?

    Haskell 有两个列表左折叠函数 foldl 以及 严格 版本 foldl 不严格的问题foldl是它建造了一座重击塔 foldl 0 1 5 gt 0 1 2 3 4 5 gt 15 这会浪费内存 并且如果列表中的项太多 可能会导致堆

随机推荐