在打印上应用函子
我一直在尝试分别打印 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`.