4

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

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

我非常粗略的理解是我应该使用 monad 转换器,这样我就可以mappend在 IO monad 中使用 single on Maybe 值,并且“do”语法应该能够支持它。我怎样才能做到这一点?

4

2 回答 2

9

使用forM_from 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只有当值结果是 a 时,它才会运行该操作Just

于 2013-09-13T20:23:01.650 回答
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 ())
  • 在 a 中的值上运行的函数Just:这​​里,(\uri -> download uri outputPath)
  • Maybe价值:maybeUri

我展示了另一种方法来表达值上的函数Just,使用部分应用的函数。

我会主张使用maybe,因为它使您无需写出 case 表达式就可以明确表明您正在处理Maybe.

于 2013-09-17T02:44:32.330 回答