如何在Haskell中构造一个no-op IO()表达式?

时间:2016-05-25 19:11:04

标签: haskell monads io-monad

以下是我正在编写的特定于域的文件IO函数的摘录:

let
    cp :: FilePath -> IO ()
    cp "." = putStr "" -- OUCH!
    cp ".." = putStr "" -- CRIKEY!
    cp fname = custom logic here...
in mapM_ cp filepaths

我理解mapM_让我们放弃/忽略所有IO ()结果,所以我想要一个更清晰的替代putStr "" ---即。 Haskell的“规范”方式来编写“一个不做任何事情的类型正确的无操作IO(或monad)表达式”。

从我的新手阅读开始,我考虑到undefined,虽然这会编译并且不会产生任何问题,但它会产生不需要的标准打印main.hs: Prelude.undefined(我使用stack runghc main.hs作为这里唯一的编码环境---它就足够了,但是上面的代码将通过目录树递归循环:所以这是一个(重新)学习更好的时间的好时机,或者说“恰当”的方式。)

1 个答案:

答案 0 :(得分:9)

这是Haskell学习曲线的一个不幸的方面:你会认为应该有一种名为

的库函数
doNothing :: IO ()

供您使用,但生态系统希望您了解return类型类中的Monad函数,这是IO实例的众多类型类之一。在这种情况下,return ()应该产生创建IO操作的预期行为(读取:效果,或thunk或promise),它们什么都不做。

您可能也对listDir and copyFile from the path-io package感兴趣,通过使用比type FilePath = String强的类型,它可以完全消除...的整个问题。请特别注意listDir如何在元组中单独返回子目录和文件。如果那不是Haskell的精神那么那是什么?它确实引入了外部依赖,但我总是在寻找能够插入优秀库的情况。