Обработка монады ввода / вывода, упрощающая синтаксис привязки - PullRequest
3 голосов
/ 16 апреля 2020

При написании небольшой программы для датирования в качестве упражнения для тренировки монад в Haskell я предложил вспомогательную функцию 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

1 Ответ

5 голосов
/ 16 апреля 2020

getCurrentTime >>= \t -> return $ utcToLocalTime z t можно заменить отображением функтора:

getCurrentTimeZone >>= \z -> fmap (utcToLocalTime z) getCurrentTime

Мы можем переписать это далее:

utcToLocalTime <$> getCurrentTimeZone <*> getCurrentTime

в localDate, вы выполняете другой функтор таким образом, мы можем записать это как:

localDate :: IO Day
localDate = localDay <$> <b>(</b>utcToLocalTime <$> getCurrentTimeZone <*> getCurrentTime<b>)</b>

или мы можем объединить два отображения функторов с:

localDate :: IO Day
localDate = <b>(localDay.) . utcToLocalTime</b> <$> getCurrentTimeZone <*> getCurrentTime

Таким образом, получается локальный день:

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