Haskell:将辅助函数内联到 do 块中

问题描述 投票:0回答:1

通过 Graham Hutton 的Haskell 编程(第二版),我刚刚成功解决了练习 10.5(第 138 页)。任务是编写一个函数

adder :: IO ()
读取
n
数字(以交互方式定义),对它们进行求和,然后打印结果,如下所示:

> adder
How many numbers? 3
5
4
6
The total is 15

函数

readInt
readLine
已给出:

readInt :: IO Int
readInt = do
  line <- readLine
  return (read line :: Int)

readLine :: IO String
readLine = do
  c <- getChar
  case c of
    '\n' -> return []
    _ -> do
      cs <- readLine
      return (c:cs)

所以我只需要编写

adder
函数:

adder :: IO ()
adder = do
  putStr "How many numbers? "
  n <- readInt
  ns <- sequence [readInt | _ <- [1..n]]
  sum <- sumUp ns
  putStr $ "The total is " ++ (show sum) ++ "\n"

sumUp :: [Int] -> IO Int
sumUp xs = return $ foldl (+) 0 xs

我对我的解决方案几乎满意,但我只想内联

sumUp
函数。但是,我不知道该怎么做。

如何将

[a] -> IO a
函数内联到
do
块中?

haskell input output monads
1个回答
0
投票

这里不需要使用

return
,我们可以使用
sum :: (Foldable f, Num a) => f a -> a
来对数字进行求和:

adder :: IO ()
adder = do
  putStr "How many numbers? "
  n <- readInt
  ns <- sequence [readInt | _ <- [1 .. n]]
  putStr $ "The total is " ++ (show (sum ns)) ++ "\n"

我们也可以重复

readInt
replicateM :: Applicative m => Int -> m a -> m [a] 
:

import Control.Monad(replicateM)

adder :: IO ()
adder = do
  putStr "How many numbers? "
  ns <- readInt >>= (`replicateM` readInt)
  putStrLn $ "The total is " ++ (show (sum ns))

至于

readInt
,可以这样实现:

readInt :: IO Int
readInt = readLn
© www.soinside.com 2019 - 2024. All rights reserved.