请考虑以下Haskell脚本,该脚本将感叹号附加到目录中的每个路径:

import System.Directory

mapPaths paths = map (++ "!") paths

transformAll = do
    paths <- listDirectory "/"
    print $ mapPaths paths

main = transformAll

如何在仍然按原样使用mapPaths的情况下从左到右将其转换为绑定(bind)操作链?

我想了解如何编写看起来像这样的函数:
doSomething :: [String] => IO [String]
doSomething paths = ???

transformAll = listDirectory "/" >>= doSomething >>= print

其中doSomething具有此签名并使用mapPaths

最佳答案

<-分解为>>=和lambda,如下所示:

transformAll = listDirectory "/" >>= \paths -> print $ mapPaths paths

然后可以这样编写所需的函数:
doSomething :: [String] -> IO [String]
doSomething paths = return $ mapPaths paths

顺便说一句,由于[String]是参数类型而不是约束,因此在其后使用一个小箭头,而不是大箭头。此外,IMO完全拥有doSomething会毫无理由地使事情变得不清楚(因为它不需要执行任何IO操作,但现在无论如何都具有IO类型)。您可以写transformAll = listDirectory "/" >>= print . mapPathstransformAll = listDirectory "/" >>= (mapPaths <&> print)来避免它(请注意,后者需要<&>中的Data.Functor)。

09-25 15:31