请考虑以下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 . mapPaths
或transformAll = listDirectory "/" >>= (mapPaths <&> print)
来避免它(请注意,后者需要<&>
中的Data.Functor
)。