Haskell 函数以字符串形式获取部分日期

发布于 2024-10-31 00:54:00 字数 716 浏览 4 评论 0原文

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

我需要在 Haskell 中获取部分日期(年、月或日)作为 String 。我发现,如果我在 GHCi 中编写以下两行

Prelude> now <- getCurrentTime
Prelude> let mon = formatTime defaultTimeLocale "%B" now

,则 mon 的类型为 String。但是,我无法将其放入函数中。例如,我尝试了以下操作:

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

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

我知道 do 语句创建了一个我不想要的 monad,但我一直无法找到任何其他解决方案来在 Haskell 中获取日期。

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

预先感谢您的任何帮助!

I have a beginner question about dates and String in Haskell.

I need to get part of date (year, month or day) as String in Haskell. I found out, that if I write the following two lines in GHCi

Prelude> now <- getCurrentTime
Prelude> let mon = formatTime defaultTimeLocale "%B" now

then mon is of type String. However, I am unable to put this in a function. I tried for instance the following:

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

But this returns type IO () and I need String (also not IO String, only String).

I understand that do statement creates a monad, which I don't want, but I have been unable to find any other solution for getting date in Haskell.

So, is there any way to write a function like this?

Thanks in advance for any help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

Smile简单爱 2024-11-07 00:54:00

如果你想返回一个代表当前时间的字符串,它必须位于 IO monad 中,因为当前时间的值总是在变化!

您可以做的是在 IO monad 中返回一个字符串:

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

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

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

If you want to return a String representing the current time, it will have to be in the IO monad, as the value of the current time is always changing!

What you can do is to return a String in the IO monad:

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

then, from your top level (e.g. in main), you can pass the String around:

> main = do
>     s <- getCurrMonth
>     ... do something with s ...
╰沐子 2024-11-07 00:54:00

如果您确实想要这种类型的纯函数,那么您需要显式地将时间作为参数传递。

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 是在其他地方执行的。

我使用了旧时间 功能,因为我在键盘上测试它,它显然没有更新的时间包。 :( 我是旧时间函​​数的新手,所以这可能会关闭几个小时,因为它使用 toUTCTime

If you really want a pure function of that sort, then you need to pass in the time explicitly as a parameter.

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

Notice how getMonthString can be pure since the IO action getClockTime is performed elsewhere.

I used the old-time functions, because I was testing it out on codepad, which apparently doesn't have the newer time package. :( I'm new to the old time functions so this might be off a couple hours since it uses toUTCTime.

岁月如刀 2024-11-07 00:54:00

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

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

祝你学习 Haskell 好运!

As Don said, there's no way to avoid using monads in this situation. Remember that Haskell is a pure functional language, and therefore a function must always return the same output given a particular input. Haskell.org provides a great explanation and introduction here that is certainly worth looking at. You'd also probably benefit from monad introduction like this one or a Haskell I/O tutorial like this one. Of course there are tons more resources online you can find. Monads can initially be daunting, but they're really not as difficult as they seem at first.

Oh, and I strongly advise against using unsafePerformIO. There's a very good reason it has the word "unsafe" in the name, and it was definitely not created for situations like this. Using it will only lead to bad habits and problems down the line.

Good luck learning Haskell!

夏日浅笑〃 2024-11-07 00:54:00

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

You can't get just a String, it has to be IO String. This is because getCurrMonth is not a pure function, it returns different values at different times, so it has to be in IO.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文