【问题标题】:How to avoid checking for empty value in Haskell?如何避免在 Haskell 中检查空值?
【发布时间】:2013-09-13 20:16:52
【问题描述】:

我试图了解 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”语法应该能够支持它。我怎样才能做到这一点?

【问题讨论】:

    标签: haskell monads maybe


    【解决方案1】:

    使用Data.Foldable中的forM_,其类型如下:

    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 时,它才会运行该操作。

    【讨论】:

    • 或者如果是downloadTo = flip download,那么在我看来,forM_ maybeUri $ downloadTo outputPath 读起来会更好。
    • @kqr 通常如果我可以 eta-reduce 参数,我会切换到使用 Data.Foldable.mapM_: mapM_ (downloadTo outputPath) maybeUri。
    【解决方案2】:

    您可以使用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 -&gt; download uri outputPath)
    • Maybe 值:maybeUri

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-01
      • 2018-08-29
      • 2020-03-16
      • 2021-07-11
      • 1970-01-01
      • 1970-01-01
      • 2020-04-01
      • 2011-05-14
      相关资源
      最近更新 更多