IO monad 处理,简化绑定语法

Sev*_*ian 3 monads haskell functional-programming

在编写一个小型日期程序作为练习在 Haskell 中处理 monad 的练习时,我想出了localDate下面的辅助函数。我更喜欢绑定链接语法而不是 do 块 - 请提供有关一种语法是否更符合 Haskell 标准的任何输入。

我的主要问题与简化localDate. 是否可以在没有两个绑定操作的情况下将 getCurrentTimeZone 和 getCurrentTime 都传递给 utcToLocalTime?

localDate :: IO(Day)
localDate = localDay <$> zoneNow where 
    zoneNow = getCurrentTimeZone >>= \z -> getCurrentTime >>= \t -> return $ utcToLocalTime z t

localDate' :: IO(Day)
localDate' = do
   z <- getCurrentTimeZone
   t <- getCurrentTime
   let zoneNow = utcToLocalTime z t
   return $ localDay zoneNow
Run Code Online (Sandbox Code Playgroud)

Wil*_*sem 5

所述getCurrentTime >>= \t -> return $ utcToLocalTime z t可以用一个函子映射来替代:

getCurrentTimeZone >>= \z -> fmap (utcToLocalTime z) getCurrentTime
Run Code Online (Sandbox Code Playgroud)

我们可以进一步将其重写为:

utcToLocalTime <$> getCurrentTimeZone <*> getCurrentTime
Run Code Online (Sandbox Code Playgroud)

在 中localDate,您执行另一个函子映射,因此我们可以将其写为:

localDate :: IO Day
localDate = localDay <$> (utcToLocalTime <$> getCurrentTimeZone <*> getCurrentTime)
Run Code Online (Sandbox Code Playgroud)

或者我们可以将两个函子映射与:

localDate :: IO Day
localDate = (localDay.) . utcToLocalTime <$> getCurrentTimeZone <*> getCurrentTime
Run Code Online (Sandbox Code Playgroud)

这因此产生了本地日:

Prelude Data.Time.Clock Data.Time.LocalTime> (localDay.) . utcToLocalTime <$> getCurrentTimeZone <*> getCurrentTime
2020-04-16
Run Code Online (Sandbox Code Playgroud)