我正在努力了解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'语法应该能够支持它。我怎样才能做到这一点?
答案 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
。