此代码从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_.
诀窍是首先创建一个要打印的所有行号的列表,然后循环遍历该列表,依次打印每个号码.所以,像这样:
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改用.
您可以计算结果,枚举它们,然后打印它们:
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)