【问题标题】:Can I use "let" inside "do"? [duplicate]我可以在“do”中使用“let”吗? [复制]
【发布时间】: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 &lt;- 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 &lt;- xs ; let {a = b; c = d} ; y &lt;- ys ; foo x a c y }.

标签: haskell


【解决方案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

【讨论】:

    猜你喜欢
    • 2015-05-11
    • 1970-01-01
    • 1970-01-01
    • 2021-11-12
    • 2011-05-01
    • 2016-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多