首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >提取嵌套一元结果:m (m ) -> m

提取嵌套一元结果:m (m ) -> m
EN

Stack Overflow用户
提问于 2014-11-25 18:46:22
回答 3查看 200关注 0票数 1

我有个功能

代码语言:javascript
复制
parseArgs :: [String] -> StdGen -> IO ()

它选择要运行的函数。主要看起来就像

代码语言:javascript
复制
main = parseArgs <$> getArgs <*> getStdGen >>= id

我遇到的问题是,parseArgs <$> getArgs <*> getStdGenIO (IO ())类型的,我使用Monad m => m (m b) -> m b类型的(>>= id)提取它。是否有一种方法可以避免在只有一行函数的情况下要求“提取”值?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-11-25 18:51:12

最简单的方法是使用join

代码语言:javascript
复制
main = join $ parseArgs <$> getArgs <*> getStdGen

就我个人而言,我更喜欢这种形式

代码语言:javascript
复制
main = join $ liftM2 parseArgs getArgs getStdGen

哪里

代码语言:javascript
复制
join   :: Monad m => m (m a) -> m a
liftM2 :: Monad m => (a -> b -> r) -> m a -> m b -> m r

或者直接用do

代码语言:javascript
复制
main = do
    args <- getArgs
    gen  <- getStdGen
    parseArgs args gen
票数 4
EN

Stack Overflow用户

发布于 2014-11-25 20:43:49

您可以为此定义一个运算符:

代码语言:javascript
复制
infixl 4 <&>

(<&>) :: Monad m => m (a -> m b) -> m a -> m b
f <&> x = f >>= (x >>=)

如果您有一个类型的函数

代码语言:javascript
复制
f :: Monad m => (a1 -> a2 -> ... -> an -> m b) -> m a1 -> m a2 -> ... -> m an -> m b

然后你可以写

代码语言:javascript
复制
fx :: Monad m => m b
fx = f <$> x1 <*> x2 <*> ... <&> xn

其中每个xi都有m ai类型。

在你的情况下,这很简单

代码语言:javascript
复制
parseArgs <$> getArgs <&> getStdGen
票数 3
EN

Stack Overflow用户

发布于 2014-11-26 09:00:04

您可以对这些参数进行配对,并使它们通过一个绑定:

代码语言:javascript
复制
main = uncurry parseArgs =<< (,) <$> getArgs <*> getStdGen

这避免了从嵌套IO中提取。诚然,它并不短,但我发现它更容易思考。

它符合doTheWork =<< getAllTheInputs的一般模式,如果代码更复杂的话,这可能是您最终安排事情的方式。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27134349

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档