Haskell函数获取日期的一部分作为字符串



我有一个关于Haskell中日期和String的初学者问题。

我需要在Haskell中获得日期(年,月或日)的一部分作为String。我发现,如果我在GHCi

中写入以下两行
Prelude> now <- getCurrentTime
Prelude> let mon = formatTime defaultTimeLocale "%B" now

monString型。然而,我无法把它放在一个函数中。例如,我尝试了以下命令:

getCurrMonth = do
    now <- getCurrentTime
    putStrLn (formatTime defaultTimeLocale "%B" now)

但这返回类型IO ()和我需要String(也不是IO String,只有String)。

我明白do语句创建了一个单子,这是我不想要的,但我一直无法找到在Haskell中获取日期的任何其他解决方案。

那么,有没有办法写出这样一个函数呢?

提前感谢您的帮助!

如果你想返回一个表示当前时间的字符串,它将在IO单子中有,因为当前时间的值总是在变化!

你能做的就是在IO单子中返回一个String:

> getCurrMonth :: IO String
> getCurrMonth = do
>    now <- getCurrentTime
>    return (formatTime defaultTimeLocale "%B" now)

然后,从你的顶层(例如在main中),你可以传递字符串:

> main = do
>     s <- getCurrMonth
>     ... do something with s ...

如果你真的想要一个这样的纯函数,那么你需要显式地将时间作为参数传入。

import System.Locale (defaultTimeLocale)
import System.Time (formatCalendarTime, toUTCTime, getClockTime, ClockTime)
main = do now <- getClockTime
          putStrLn $ getMonthString now
getMonthString :: ClockTime -> String
getMonthString = formatCalendarTime defaultTimeLocale "%B" . toUTCTime

注意getMonthString可以是纯的,因为IO操作getClockTime是在其他地方执行的。

我使用了旧的函数,因为我是在codepad上测试它的,它显然没有较新的时间包。:(我对旧的时间函数不熟悉,所以这可能会关闭几个小时,因为它使用toUTCTime .

正如Don所说,在这种情况下无法避免使用单子。请记住,Haskell是一种纯函数式语言,因此给定特定的输入,函数必须始终返回相同的输出。Haskell.org在这里提供了很好的解释和介绍,当然值得一看。您也可能受益于monad的介绍,如本文或Haskell I/O教程,如本文。当然,你可以在网上找到更多的资源。单子一开始可能会让人望而生畏,但它们并不像一开始看起来那么难。

哦,我强烈建议不要使用unsafePerformIO。它的名字中有"不安全"这个词是有充分理由的,而且它绝对不是为这种情况而创建的。使用它只会导致坏习惯和问题。

祝你学习Haskell好运!

你不能只得到一个String,它必须是IO String。这是因为getCurrMonth不是一个纯粹的函数,它在不同的时间返回不同的值,所以它必须在IO中。

相关内容

  • 没有找到相关文章

最新更新