如何使用stdin中的数据执行某些操作,逐行,最多次并打印Haskell中的行数

ICT*_*lor 6 monads haskell

此代码从stdin的第一行读取要处理的行数,然后循环number_of_lines_to_process次,进行一些计算并打印结果.我希望它在"#"之后的"Line#"中打印行号,但我不知道如何获取它

import IO
import Control.Monad (replicateM)

main :: IO ()

main = do
    hSetBuffering stdin LineBuffering
    s <- getLine
    let number_of_lines_to_process = read s :: Integer
    lines <- replicateM (fromIntegral(number_of_lines_to_process)) $ do
        line <- getLine
        let number = read line :: Integer
            result = number*2 --example
        putStrLn ("Line #"++": "++(show result)) --I want to print the number of the iteration and the result
    return ()
Run Code Online (Sandbox Code Playgroud)

我想这个问题的解决方案非常简单,但我不熟悉Haskell(第一次在其中编码),我没有找到任何办法.有人可以帮忙吗?

Chr*_*lor 13

您可以使用forM_而不是replicateM:

import IO
import Control.Monad

main :: IO ()
main = do
    hSetBuffering stdin LineBuffering
    s <- getLine
    let number_of_lines_to_process = read s :: Integer

    forM_ [1..number_of_lines_to_process] (\i -> do
        line <- getLine
        let number = read line :: Integer
            result = number * 2
        putStrLn $ "Line #" ++ show i ++ ": " ++ show result)
Run Code Online (Sandbox Code Playgroud)

请注意,因为您使用forM_(丢弃每次迭代的结果)return (),所以最后不需要额外的 - do块返回最后一个语句的值,在这种情况下()是返回的值forM_.

  • 没问题.旁白:我有兴趣知道为什么这是低估的. (3认同)

dfl*_*str 9

诀窍是首先创建一个要打印的所有行号的列表,然后循环遍历该列表,依次打印每个号码.所以,像这样:

import Control.Monad

import System.IO

main :: IO ()
main = do
  hSetBuffering stdin LineBuffering
  s <- getLine
  let lineCount = read s :: Int
      -- Create a list of the line numbers
      lineNumbers = [1..lineCount]

  -- `forM_` is like a "for-loop"; it takes each element in a list and performs
  -- an action function that takes the element as a parameter
  forM_ lineNumbers $ \ lineNumber -> do
    line <- getLine
    let number = read line :: Integer
        result = number*2 --example
    putStrLn $ "Line #" ++ show lineNumber ++ ": " ++ show result
  return ()
Run Code Online (Sandbox Code Playgroud)

阅读的定义forM_.

顺便说一句,我不建议使用旧的Haskell98 IO库.请System.IO改用.


ntc*_*tc2 5

您可以计算结果,枚举它们,然后打印它们:

import IO
import Control.Monad (replicateM)

-- I'm assuming you start counting from zero
enumerate xs = zip [0..] xs

main :: IO ()

main = do
    hSetBuffering stdin LineBuffering
    s <- getLine
    let number_of_lines_to_process = read s :: Integer
    lines <- replicateM (fromIntegral(number_of_lines_to_process)) $ do
        line <- getLine
        let number = read line :: Integer
            result = number*2 --example
        return result
    mapM_ putStrLn [ "Line "++show i++": "++show l | (i,l) <- enumerate lines ]
Run Code Online (Sandbox Code Playgroud)