如何从 stdin 读取 haskell 中单独一行上的每个整数来初始化整数列表?

How to initialize a list of integers from stdin reading each integer on a separate line in haskell?

我是 Haskell 的新手,但我知道 C++ 和 Java。现在我想知道如何读取类似于此伪代码的整数列表?

   cout << "Please enter the size of your list";
   cin >> list_size;
   int mylist[listsize];
   for (int i = 0 ; i<list_size; i++) {
      cout<< "please enter the next number:";
      cin>> number;
     mylist[i]=number;
    }

链接问题中给出的答案使用惰性IO(通过getContents)。

就我个人而言,我不喜欢惰性 IO,而且我认为试图理解它如何与 do-notation 结合使用会导致混淆。所以这是一个不使用惰性 IO 的答案:

import Control.Monad(replicateM)

main :: IO ()
main = do
    putStrLn "Please enter the size of your list"
    times <- readLn
    ns <- replicateM times 
                     (do putStrLn "please enter the next number: "
                         readLn :: IO Int) -- type annotation to remove ambiguity
    print ns

replicateM 接受一个数字 n 和一个有效的动作,returns 一个执行原始 n[= 的新动作40=] 次和 returns 包含结果的列表。

如果我想为每个号码显示不同的提示信息怎么办?

这可以理解为对提示消息列表的有效转换,将每条消息替换为输入的值。一种"effectful map".

函数traverse can be used here. Or perhaps for,它是traverse的翻转版本:

{-# language ScopedTypeVariables #-}

import Data.Traversable (for)

main :: IO ()
main = do
    putStrLn "Please enter the size of your list"
    times :: Int <- readLn
    ns <- for [1..times]
              (\prompt -> do putStrLn ("enter " ++ show prompt)
                             readLn :: IO Int) -- type annotation to remove ambiguity
    print ns

示例中需要 :: IO Int 注释,因为 readLn 可以读取任何具有 Read 实例的类型,但我们没有对结果执行任何特定于 Int 的操作,所以我们需要以某种方式通知编译器有关类型的信息。