(>>=)
的类型是
(>>=) :: Monad m => m a -> (a -> m b) -> m b
我想要一个具有以下类型的函数:
(Monad m, Monad n) => m a -> (a -> n b) -> n b
此函数可用于将不同的 monad 链接在一起。
当我尝试从命令行参数-p 3000
获取3000
时,我遇到了这个问题:
main = getArgs >>= (\args -> (elemIndex "-p" args) >>= (\id -> warpDebug (fromIntegral.read (args !! (id+1))) Ilm))
这显然不会编译,因为 getArgs
返回一个 IO [String]
并且 elemIndex
返回一个 Maybe Int
。可以使用上述类型的函数来优雅地解决这个问题。我的问题是:
- 这个函数已经定义了吗? (Hoogle没有找到任何)
- 如果没有,可能是由于某种原因。那到底是什么原因呢?这被认为是一种不好的做法吗?我认为这是比使用 case 表达式更好的方法。
最佳答案
这样的函数不存在。事实上,如果你将 n
作为恒等 monad,它会允许你构造一个函数 m a -> a
,这显然不能为所有 monad 定义。
要解决“组合”两个 monad 的一般问题,您可以查看 monad transformers .
但是,在您的示例中使用 monad 转换器似乎有些过分了。您可以简单地定义一个函数 [String] -> Maybe Args
(对于某些自定义类型 Args
- 在示例中说 Int
)命令行参数处理,然后从 IO
monad 中对结果进行模式匹配(或使用 maybe
)。
关于haskell - 类似于 (>>=) 的函数,但返回不同的 monad,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8614053/