如何在 Haskell 中构造一个空操作 IO() 表达式?

How to construct a no-op IO() expression in Haskell?

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

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

我明白 mapM_ 让我们 drop/ignore 所有 IO () 结果,所以我想要一个更干净的替代 putStr "" --- 即。 Haskell的"canonical"写法"a type-correct no-op IO (or monad) expression that does nothing".

从我的新手阅读来看,我想到了 undefined,虽然这可以编译并且不会导致任何问题,但它会给出不需要的标准输出打印 main.hs: Prelude.undefined(我使用 stack runghc main.hs 作为 sole 这里的编码环境 --- 这已经足够了,但是 上面的代码将在目录树中递归循环:所以是个好时机(重新)了解更好的方法,或者更确切地说 "the proper" 方法)。

这是 Haskell 学习曲线的一个不幸方面:你会认为应该有某种库函数叫做

doNothing :: IO ()

供您使用,但生态系统希望您知道 Monad 类型类中的 return 函数,IO 实例的众多类型类之一。在这种情况下,return () 应该产生预期的行为,即创建一个什么都不做的 IO 动作(读作:effect,或 thunk,或 promise)。

您可能还对 listDir and copyFile from the path-io package 感兴趣,它通过使用比 type FilePath = String 更强的类型能够完全消除 ... 的整个问题.请特别注意如何将 listDir returns 子目录和文件分开放在一个元组中。如果这不符合 Haskell 的精神,那么什么才是?它确实带来了外部依赖性,但我一直在寻找可以插入那个优秀库的情况。