Haskell:将内联辅助功能导入 do 块

Haskell: inline auxiliary function into do block

提问人:Patrick Bucher 提问时间:8/31/2023 更新时间:9/1/2023 访问量:52

问:

通过Graham Hutton的Programming in Haskell(第二版),我刚刚设法解决了练习10.5(第138页)。任务是编写一个函数来读取数字(以交互方式定义),将它们相加,然后打印结果,如下所示:adder :: IO ()n

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

函数 和 已经给出为:readIntreadLine

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 ado

Haskell 输入 输出 单子

评论

0赞 Daniel Wagner 9/1/2023
你只是使用你写的平等。,因此 in 可以替换为该方程的 RHS:。(但这不是一个真正的答案,因为在这种特定情况下,有更好的解决方案。sumUp ns = return $ foldl (+) 0 nssumUp nssum <- sumUp nssum <- return $ foldl (+) 0 ns

答:

2赞 willeM_ Van Onsem 8/31/2023 #1

这里没有必要用,我们可以用 sum :: (Foldable f, Num a) => f a -> a 来总结数字:return

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

我们也可以通过 replicateM :: Applicative m => Int -> m a -> m [a]:readInt

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