将 getArgs 从 IO [String] 转换为 IO [Int]
Transform getArgs from IO [String] to 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
有没有一种方法可以根据 getArgs
(来自 System.Environment
)编写函数 getIntArgs
?
先在脑海中解开它。您需要一个来自 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)
我想编写如下程序:
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
有没有一种方法可以根据 getArgs
(来自 System.Environment
)编写函数 getIntArgs
?
先在脑海中解开它。您需要一个来自 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)