我正在尝试从键盘读取的总数但是我没有得到它,在函数sumNums例如我把7和我可以输入8个数字但只需要添加7,我想要输入7并添加7。在主要功能中,我不能使用sumNums
getInt :: IO Int
getInt = do
s <- getLine
return (read s)
sumNums :: Integer -> IO Int
sumNums n = do
x<-getInt
if n==0
then return 0
else do
rest <- sumNums (n-1)
return (x+rest)
main = do putStrLn "Type numbers: "
suma <- sumNums 7
putStrLn "Sum: " ++ show sum
average <- suma/7
putStrLn "Average: " ++ show average
答案 0 :(得分:3)
主要问题是你读了一个数字然后你检查n
的值是否表明你应该读另一个数字。而是首先检查n
的值。
sumNums 0 = return 0
sumNums n = do
rest <- sumNums (n - 1)
x <- getInt
return (x + rest)
但是,尽可能避免显式递归。许多常见模式已被抽象出高阶函数。
在这里,你想要什么?您想要汇总一个数字列表,您可以通过多次运行getInt
来获得这些数字。从replicate
功能开始,重复getInt
所需的次数:
> :t replicate 3 getInt
replicate 3 getInt :: [IO Int]
然后使用sequence
将所有整数提取到一个列表中。
> :t sequence (replicate 3 getInt)
sequence (replicate 3 getInt) :: IO [Int]
最后,您可以将sum
提升到IO
monad以添加数字。
> :t sum <$> sequence (replicate 3 getInt)
sum <$> sequence (replicate 3 getInt) :: IO Int
因此,您可以简单地将sumNums
写为
sumNums n = sum <$> sequence (replicate n getInt)
更简单地说,replicateM
将sequence
与replicate
结合在一起(实际上是replicateM = (sequence . ) . replicate
)。
import Control.Monad
sumNums n = sum <$> replicateM n getInt