【问题标题】:Haskell IO RecursionHaskell IO 递归
【发布时间】:2012-03-12 08:15:53
【问题描述】:

我有代码:

read :: IO [Line]
read = do
  line <- getLine
  let count = length line
  line2 <- getLine 
  if (length line2 /= count) 
  then error "too long or too short"
  else read

我想要做的是,基于用户必须的第一行的长度 输入 length-1 多行,如果其中任何一行的长度不同 作为原始行,将显示错误消息。

现在我的代码只是一个无限循环,因为我无法弄清楚 如何输入长度为 1 的更多行。对此的一些指导将不胜感激。

编辑:行是字符串类型

【问题讨论】:

  • 你的代码是一个无限循环的原因是因为你允许它停止的唯一方法是错误。否则它将始终跟随 if 语句的另一个分支并一次又一次地递归。

标签: haskell recursion io


【解决方案1】:

您可以使用replicateM 将操作复制一定次数并收集结果。在您的情况下,该操作是抓取一条线,测试其长度,如果无效则出错。因此,您可以使用以下内容来完成您的工作:

import Control.Monad (replicateM)

read :: IO [Line]
read = do
  line <- getLine
  let count = length line
  lines <- replicateM (count-1) $ do
    line <- getLine
    if length line /= count
    then fail "too long or too short"
    else return line
  return $ line : lines

【讨论】:

  • 谢谢! ReplicateM 看起来不错,尽管它似乎不会在必要时停止(它超过了 count-1 限制!)
  • replicateM 完美运行,如果有问题,可能在您的代码的其余部分。当一段标准的简单代码似乎完全没有达到它的目的时,这是一个合理的立场:不要责怪标准函数并在你自己的代码中寻找错误。如果您仍然找不到错误,请在此处或 #haskell 上向有经验的 Haskeller 展示您的代码。如果他们仍然找不到错误,是时候开始怀疑标准库了。
  • 我猜,只是上面的代码对我来说看起来不错,我会继续调整它,看看我是否能找到修复...谢谢
猜你喜欢
  • 1970-01-01
  • 2011-09-01
  • 2013-12-06
  • 2019-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多