【问题标题】:Read n lines input with Haskell使用 Haskell 读取 n 行输入
【发布时间】:2019-04-07 10:25:27
【问题描述】:

我正在努力学习编写 Haskell 程序。我无法阅读 n 行输入。

输入是

n
a b (<----- n times)

其中nab 是数字。

我试过了

input = []

readString 0 = return()
readString n =
 do
  z <- getLine
  z:input
  readString (n-1)

main = do
 n <- getLine
 readString n

这会引发错误。如何在 Haskell 中正确循环读取?

【问题讨论】:

  • z:input 应该做什么?
  • @melpomene 猜测一下:戴上你的 mutable-language-hat 并将其视为input = z:input 的拼写错误。
  • 对,那是我没注意到的错字
  • “抛出错误”...请问错误具体是什么意思?
  • @kaiya 谢谢,但该链接主要是为未来的访问者准备的,他们可能不会遇到与您完全相同的问题,并且可能希望被定向到其他资源。

标签: loops haskell input getline


【解决方案1】:

Haskell 是不可变的:一旦你写了

input = []

那么input 就是[] 永远永远,阿门。您可以使用与“更改”值n 相同的技术来获得“更改”值input,也就是说,将其作为参数传递给readString

readString 0 input = return input
readString n input = do
  z <- getLine
  readString (n-1) (z:input)

如果你这样做,你会发现你输入的行从末尾开始被放入input——所以它们以相反的顺序出现! (如果您的代码 sn-p 有效,它也会以这种方式运行。)一个简单的解决方法是更改​​基本情况:

readString 0 input = return (reverse input)

更惯用的解决方法是完全取消参数,首先以正确的顺序返回内容:

readString 0 = return []
readString n = do
  z <- getLine
  zs <- readString (n-1)
  return (z:zs)

当您熟悉标准库时,您可能会先毕业到

readString 0 = return []
readString n = liftA2 (:) getLine (readString (n-1))

然后完全跳过readString的定义,转而重写main

main = do
  n <- readLn
  lines <- replicateM n getLine
  ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-14
    • 2011-12-09
    • 1970-01-01
    • 2014-05-28
    • 1970-01-01
    • 2012-04-02
    相关资源
    最近更新 更多