如何避免在Haskell中检查空值?

时间:2013-09-13 20:16:52

标签: haskell monads maybe

我正在努力了解Haskell程序如何避免测试“空值”。我正在努力摆脱这个程序中的案例表达:

main =  do url:outputPath:[] <- getArgs
         let maybeUri = parseURI url
         case maybeUri of
              Just uri -> download uri outputPath
              Nothing -> return ()

我非常粗略的理解是我应该使用monad变换器,这样我就可以在IO monad中对Maybe值使用单mappend,而'do'语法应该能够支持它。我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:9)

使用forM_中的Data.Foldable,其中包含以下类型:

forM_ :: (Monad m, Foldable t) => t a -> (a -> m b) -> m ()

Maybe实现了Foldable类,其行为类似于包含零个或一个元素的列表,因此当您将上述类型签名中的t专门化为Maybe时:

forM_ :: (Monad m) => Maybe a -> (a -> m b) -> m ()

你这样使用它:

forM_ maybeUri $ \uri -> download uri outputPath

只有当Maybe值变为Just时,它才会执行操作。

答案 1 :(得分:0)

您可以使用Data.Maybe.maybe(它也在Prelude中,因此无需导入):

main = do
  url:outputPath:[] <- getArgs
  let maybeUri = parseURI url
  maybe (return ()) (\uri -> download uri outputPath) maybeUri
  -- The above can also be written as:
  -- maybe (return ()) ((flip download) outputPath) maybeUri

maybe需要:

  • Nothing的情况下运行的函数:此处为(return ())
  • 运行Just内的值的函数:此处为(\uri -> download uri outputPath)
  • Maybe值:maybeUri

我展示了一种使用部分应用函数在Just值上表达函数的替代方法。

我会主张使用maybe因为它使得它明确,而不必写出案例表达式,而是处理Maybe