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!
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 ...
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
.
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!
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.
精彩评论