在打印上应用函子

sim*_*amt 3 haskell functor

我一直在尝试分别打印 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)

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

lef*_*out 5

如果您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)

  • 我来这里是为了宣传 `print =&lt;&lt; getCurrentTime`。 (3认同)