我可以在“do”中使用“let”吗? [复制]
Posted
技术标签:
【中文标题】我可以在“do”中使用“let”吗? [复制]【英文标题】:Can I use "let" inside "do"? [duplicate] 【发布时间】:2021-10-22 09:51:22 【问题描述】:这个简单的程序打印输入文件中数字列表的总和和乘积。
main :: IO ()
main = do
text <- readFile "./input.txt"
print $ sum [read line | line <- lines text]
print $ product [read line | line <- lines text]
-
Example input:
1
2
3
4
Example output:
10
24
-
最好避免重复[read line | line <- lines text]
。如果我提取函数printSumAndProduct
,我可以使用let
表达式来执行此操作:
main :: IO ()
main = do
text <- readFile "./input.txt"
printSumAndProduct text
printSumAndProduct :: String -> IO ()
printSumAndProduct text =
let numbers = [read line | line <- lines text]
in do
print $ sum numbers
print $ product numbers
但是,我更喜欢只有一个函数,main
。 是否可以在没有单独的函数printSumAndProduct
的情况下做到这一点?
这是我尝试过的:
main :: IO ()
main = do
text <- readFile "./input.txt"
let numbers = [read line | line <- lines text]
in do
print $ sum numbers
print $ product numbers
但这是一个语法错误:
main.hs:5:3: error: parse error on input ‘in’
【问题讨论】:
(也许有更好的副本-但关键点显示在已接受答案的点“2”中:在do
内,您可以简单地使用let
“声明”而不用in
)
啊——我想是的,谢谢!
只需在最后一个“in”关键字的左侧再插入一个空格,它就会编译。缩进规则有一些微妙之处。似乎在那种情况下(做构造)“in”子句必须从属于“let”子句。请参阅 user395760 在重复问题中的回答。
@jpmariner 与 in
从属于 let
子句无关;整个let ... in
表达式对缩进不敏感(其中的绑定块是,但如果in
部分无关紧要,则缩进)。问题是每行缩进以匹配 do
块中语句的对齐方式都被视为块中 new 语句的开始,而 do
块语句可以'不要以in
开头。
.... 所以我们还应该注意,使用显式的 ;
分隔符将消除所有此类由缩进引起的问题。为了可读性,我们仍然应该使用良好的缩进,但如果我们稍微偏离它仍然可以工作:do x <- xs ; let a = b; c = d ; y <- ys ; foo x a c y
.
【参考方案1】:
通过Robin Zigmond的评论链接In Haskell, when do we use in with let?:
main :: IO ()
main = do
text <- readFile "./input.txt"
let numbers = [read line | line <- lines text]
print $ sum numbers
print $ product numbers
【讨论】:
以上是关于我可以在“do”中使用“let”吗? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
您可以在带有实体框架核心的 Iqueryable 中使用带有 let 语句的字典吗?
为啥 for..of / for..in 循环可以使用 const 而普通的 for 循环在 JS 中只能使用 let 或 var 作为其变量? [复制]