haskell - 将 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
( getArgs
from System.Environment
) 来编写函数?
解决方案
先把它放在你的头上。您需要一个从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)
推荐阅读
- r - 如何从大数据中选择每月最后一天交易的会员
- asp.net - 为什么在.net 4.8上运行的asp.net会添加http头x-aspnet-version: 4.0.30319
- spring-boot - Spring Boot 2 - 使用 @async 注释的方法不称为异步
- r - R Starwars 按眼睛颜色计算性别
- ruby - RSpec 让字符串和哈希 - 语法错误
- javascript - 做一个表单提交调用一个函数,而不是在它的 id 上创建特定的提交
- php - 隧道/代理 SSH
- boost - 实现一个 BOOST_TEST test_runner 来运行来自不同共享库的多个测试
- android - 禁用剪贴板选项 Edittext
- excel - 谷歌表格使用当前表格中计算的动态值引用另一张表格中的值