如何在 Haskell 中将其更改为 while 循环?

Dou*_*wit 3 haskell functional-programming ghc ghci

Haskell 具有挑战性!到目前为止我想到的是,我可以执行以下操作来模拟 Haskell 中的 for 循环以从用户那里获取数字列表:

myList <- sequence [putStr "Enter an integer: " >> (
    \s -> read s :: Int) <$> getLine | t <- [1..5]]
Run Code Online (Sandbox Code Playgroud)

伟大的!所以myList包含我输入的五个整数。伟大的!但问题就在这里。而不是迭代五次(或任何有限次数)的 for 循环如何将上述内容转换为等效的 while 循环?

所以我在想的是这个,但不幸的是它不起作用。有什么“神奇”的方法可以让它发挥作用吗?

takeWhile (\x -> x > 0) $ sequence [putStr "Enter an integer: " >> (
    \s -> read s :: Int) <$> getLine | t <- [1..]]
Run Code Online (Sandbox Code Playgroud)

问题在于它(\x -> x > 0)适用于 Int。(或任何 Num 类型。)但是来自该列表的实际上是一堆 IO Int。 x > 0返回一个布尔值。我需要一个返回 IO Bool 的函数吗?我有点失落。有人可以为我指出Haskell启蒙之路吗?!自己研究这个并不容易!!!非常感谢!!!

ama*_*loy 7

你不能用sequence无限的 IO 操作列表来编写这个程序。您在序列“外部”执行的任何操作都将无法检查其内容,并且序列内部的任何操作都无法阻止它继续进行。

相反,您必须编写一个读取 Int 的 IO 操作,检查它,然后决定是继续还是停止。

positiveInts :: IO [Int]
positiveInts = do
  putStr "Enter an integer: "
  i <- readLn
  if i <= 0
    then pure []
    else (i:) <$> positiveInts
Run Code Online (Sandbox Code Playgroud)