在打印上应用函子

我一直在尝试分别打印 2 个值,并尝试了以下代码:

import System.Directory
main = getCurrentDirectory >>= x -> (print <$> doesFileExist x) >> (print <$> doesDirectoryExist x)

但它不打印任何内容,但以下代码工作正常:

import System.Directory
main = getCurrentDirectory >>= x -> doesFileExist x >>= print >> doesDirectoryExist x >>= print

为什么第一个代码不打印任何内容的任何原因?

回答

如果您print对 IO 操作进行fmap ,则不会得到IO执行此打印的操作。你只是得到一个 IO 动作,它执行原始动作所具有的任何副作用,但它不是产生可打印的值作为结果,而是产生另一个IO动作作为结果,然后你可以在单独的步骤中执行:

import Control.Applicative
import Data.Time

printCurrentTime :: IO ()
printCurrentTime = do
   tPrinter <- print <$> getCurrentTime
   tPrinter

或者,没有do符号,

printCurrentTime = print <$> getCurrentTime >>= tPrinter -> tPrinter

换句话说,

printCurrentTime = print <$> getCurrentTime >>= id

根据 monad 定律,f <$> a >>= b与 相同a >>= b . f,即

printCurrentTime = getCurrentTime >>= id . print

这与简单地相同

printCurrentTime = getCurrentTime >>= print

那可以用do符号写成

printCurrentTime = do
   t <- getCurrentTime
   print t

  • I'm here to evangelize `print =<< getCurrentTime`.

以上是在打印上应用函子的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>