首页 > 解决方案 > 将 getArgs 从 IO [String] 转换为 IO [Int]

问题描述

我想写一个像下面这样的程序:

add :: Int -> Int -> Int
add a b = a + b

main :: IO ()
main = do
    args <- getIntArgs
    case args of
        [a,b] -> putStrLn $ show $ add a b

有没有办法可以用getIntArgs( getArgsfrom System.Environment) 来编写函数?

标签: haskellmonads

解决方案


先把它放在你的头上。您需要一个从IO [String] -> IO [Int]. 首先考虑一个来自的函数f a -> f b——嗯,就是fmap

然后我们只需要找到一个从a -> b. 在这种情况下a ~ [String]b ~ [Int]。现在我们看到另一个函子包装了我们的具体类型——fmap再次工作,这次抽象掉了[]而不是IO.

现在我们需要一个函数String -> Int。这是read.

getIntArgs = fmap (fmap read) getArgs

因为f (g x) = (f . g) x,我们可以写(并且应该更喜欢,它是 Haskelly-er)(fmap . fmap) read $ getArgs:。

实际上,您的整个功能就是:

main :: IO ()
main = (fmap (sum . fmap read) getArgs) >>= print
-- assuming you're okay replacing `(+)` with `sum`

-- if not:
main = (fmap (uncurry (+) . listToTuple . fmap read) getArgs) >>= print
  where
  listToTuple [a, b] = (a, b)

推荐阅读