haskell方式接受用户输入用户输入的次数?

mac*_*912 8 haskell

我刚刚开始学习haskell,这是一种与我习惯的(C风格语言)不同的思维方式.

无论如何,对于我正在研究的一个问题,我需要接收用户输入.它将以形式出现

2
10
20
Run Code Online (Sandbox Code Playgroud)

例如.格式是第一行表示后面的行数.我的第一个想法是,我会读取第一行,然后循环运行这么多次.这是Haskell!据我所知,循环是不可能的.

我的下一个想法是,我将使用第一行输入来填充列表,其中包含其他n个数字.我不知道怎么会这样做.我在这里,因为我甚至不确定我会搜索什么来解决它.

在此先感谢我向我展示了哈克尔的做法.到目前为止这是艰难的,但我听到了"开悟"的人的好评,所以我觉得自己学习语言不会有什么坏处.

这里的代码只运行一次,但需要为第一行后面的第二行到第n行运行一次.

l n = (-1)^n/(2*(fromIntegral n)+1)
a m = sum [l n | n <- [0..(m-1)]]
main =
    do  b <- readLn
        print (a b)
Run Code Online (Sandbox Code Playgroud)

(另外,我很想知道我是否可以对我的代码进行其他改进,但在这种特殊情况下,竞争是以尽可能少的字符解决问题.我不想得到更多其他人试图寻找同一问题的答案.)

编辑:谢谢大家的答案.我最终得到的东西表现得我想要它.我把下面的代码放在后代.可悲的是,即使它通过了测试用例,它们测试的实际数据也不同,他们告诉我的只是我得到了"错误的答案".此代码"有效",但没有得到正确的答案.

import Control.Monad
l n = (-1)^n/(2*(fromIntegral n)+1)
a m = sum [l n | n <- [0..(m-1)]]
main =
    do  b <- readLn
        s <- replicateM b readLn
        mapM_ print [a c | c <- s]
Run Code Online (Sandbox Code Playgroud)

Car*_*arl 10

首先,你可以在haskell中循环.它一直在发生.你只是没有语法结构,因为不需要它们.

大多数情况下,常见的通用循环被放入库中.在这种情况下,您需要的循环位于模块中的标准库中Control.Monad.它被称为replicateM.它有类型签名Monad m => Int -> m a -> m [a].要为您的案例专门设置此签名,它就具有该类型Int -> IO Int -> IO [Int].第一个参数是循环的次数.第二个是在每个循环上运行的IO操作.该函数的结果是一个IO动作,它产生输入列表.

因此,如果添加inputs <- replicateM b readLn到do块中,它会将一个名为inputsscope 的列表放入包含b第一个输入行之后的输入行的值.然后,您可以在这些行上映射解决方案功能.


Ven*_*nge 6

卡尔的解决方案可行,但它有点不透明.如果你想写出来,你可以这样做:

readLines :: Int -> IO [Int]
readLines 0 = return []
readLines n = do
   x <- fmap read getLine
   rest <- readLines (n-1)
   return $ x : rest

readSomeNumberOfLines :: IO [Int]
readSomeNumberOfLines = do
   n <- fmap read getLine
   readLines n
Run Code Online (Sandbox Code Playgroud)

你在这里做的readLines是你实际上是在定义明显的基本情况(读取0个东西,只是给出一个空列表)和递归情况(读取n个东西,读取一个东西,然后读取另一个n-1)事情,然后将它们组合在一起).