我有个功能
parseArgs :: [String] -> StdGen -> IO ()它选择要运行的函数。主要看起来就像
main = parseArgs <$> getArgs <*> getStdGen >>= id我遇到的问题是,parseArgs <$> getArgs <*> getStdGen是IO (IO ())类型的,我使用Monad m => m (m b) -> m b类型的(>>= id)提取它。是否有一种方法可以避免在只有一行函数的情况下要求“提取”值?
发布于 2014-11-25 18:51:12
最简单的方法是使用join
main = join $ parseArgs <$> getArgs <*> getStdGen就我个人而言,我更喜欢这种形式
main = join $ liftM2 parseArgs getArgs getStdGen哪里
join :: Monad m => m (m a) -> m a
liftM2 :: Monad m => (a -> b -> r) -> m a -> m b -> m r或者直接用do
main = do
args <- getArgs
gen <- getStdGen
parseArgs args gen发布于 2014-11-25 20:43:49
您可以为此定义一个运算符:
infixl 4 <&>
(<&>) :: Monad m => m (a -> m b) -> m a -> m b
f <&> x = f >>= (x >>=)如果您有一个类型的函数
f :: Monad m => (a1 -> a2 -> ... -> an -> m b) -> m a1 -> m a2 -> ... -> m an -> m b然后你可以写
fx :: Monad m => m b
fx = f <$> x1 <*> x2 <*> ... <&> xn其中每个xi都有m ai类型。
在你的情况下,这很简单
parseArgs <$> getArgs <&> getStdGen发布于 2014-11-26 09:00:04
您可以对这些参数进行配对,并使它们通过一个绑定:
main = uncurry parseArgs =<< (,) <$> getArgs <*> getStdGen这避免了从嵌套IO中提取。诚然,它并不短,但我发现它更容易思考。
它符合doTheWork =<< getAllTheInputs的一般模式,如果代码更复杂的话,这可能是您最终安排事情的方式。
https://stackoverflow.com/questions/27134349
复制相似问题