有没有更好的方法来编写这个 haskell 函数?

Is there a better way to write this haskell function?

我刚刚开始重新学习 Haskell(我已经尝试过几次)并且我写了一个小函数,它应该将文件下载到给定的文件路径。 如果 URL 是 Some 它应该下载文件,如果它是 Nothing 它应该什么都不做。

downloadFile :: URL -> FilePath -> IO ()
downloadFile url fp = ...        

maybeDownloadFile :: Maybe URL -> FilePath -> IO ()
maybeDownloadFile ( Just url ) fp = downloadFile url fp
maybeDownloadFile Nothing fp = return ()

所以它本质上只是包装了 downloadFile 函数,但是用 Maybe URL 而不是 URL。 问题是,我觉得这可以通过 monadic 运算符(或者可能使用仿函数)而不使用 match 表达式来更优雅地实现。 有这样的运营商吗?

你的功能真的很干净。我可以看着它并很快说出它的作用。顶层的模式匹配,很明显,功能很短,一眼就能认出来。

如果您确实想要一个很好的组合器,那么它确实存在。它在 extra 包中称为 whenJust

maybeDownloadFile :: Maybe URL -> FilePath -> IO ()
maybeDownloadFile url fp = whenJust url (\url -> downloadFile url fp)

但这没什么大不了的。你现在的功能没问题。

附带说明一下,我之前并不知道 whenJust。我通过在 Hoogle 中搜索类型

找到了它
Maybe a -> (a -> IO ()) -> IO ()

即“我有一个 Maybe,如果它不为空,我想做一个 IO 的事情”。 whenJust 是该搜索下的第一个结果。 Hoogle 可以成为在标准库和相关库中查找此类内容的非常有用的工具。

Just 上采取一些行动,而在 Nothing 上什么也不做,正是 traverse_(或 mapM_)所做的。翻转你的论点,让它更漂亮。

downloadFile :: FilePath -> URL -> IO ()
downloadFile fp url = ...

maybeDownloadFile :: FilePath -> Maybe URL -> IO ()
maybeDownloadFile = traverse_ . downloadFile