Haskell 函数以字符串形式获取部分日期
我有一个关于 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果你想返回一个代表当前时间的字符串,它必须位于 IO monad 中,因为当前时间的值总是在变化!
您可以做的是在 IO monad 中返回一个字符串:
然后,从您的顶层(例如在 main 中),您可以传递该字符串:
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:
then, from your top level (e.g. in main), you can pass the String around:
如果您确实想要这种类型的纯函数,那么您需要显式地将时间作为参数传递。
请注意
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.
Notice how
getMonthString
can be pure since the IO actiongetClockTime
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
.正如 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!
你不能只得到一个字符串,它必须是 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.