我一直在尝试分别打印 2 个值,并尝试了以下代码:
import System.Directory
main = getCurrentDirectory >>= \x -> (print <$> doesFileExist x) >> (print <$> doesDirectoryExist x)
Run Code Online (Sandbox Code Playgroud)
但它不打印任何内容,但以下代码工作正常:
import System.Directory
main = getCurrentDirectory >>= \x -> doesFileExist x >>= print >> doesDirectoryExist x >>= print
Run Code Online (Sandbox Code Playgroud)
为什么第一个代码不打印任何内容的任何原因?
如果您print对 IO 操作进行fmap ,则不会得到IO执行此打印的操作。你只是得到一个 IO 动作,它执行原始动作所具有的任何副作用,但它不是产生可打印的值作为结果,而是产生另一个IO动作作为结果,然后你可以在单独的步骤中执行:
import Control.Applicative
import Data.Time
printCurrentTime :: IO ()
printCurrentTime = do
tPrinter <- print <$> getCurrentTime
tPrinter
Run Code Online (Sandbox Code Playgroud)
或者,没有do符号,
printCurrentTime = print <$> getCurrentTime >>= \tPrinter -> tPrinter
Run Code Online (Sandbox Code Playgroud)
换句话说,
printCurrentTime = print <$> getCurrentTime >>= id
Run Code Online (Sandbox Code Playgroud)
根据 monad 定律,f <$> a >>= b与 相同a >>= b . f,即
printCurrentTime = getCurrentTime >>= id . print
Run Code Online (Sandbox Code Playgroud)
这与简单地相同
printCurrentTime = getCurrentTime >>= print
Run Code Online (Sandbox Code Playgroud)
那可以用do符号写成
printCurrentTime = do
t <- getCurrentTime
print t
Run Code Online (Sandbox Code Playgroud)