OneEyeQuestion
OneEyeQuestion

Reputation: 742

How to store current date in a record as a Day type only?

How can I store in a record the current date as a Day type? Is this the correct way of doing it? I want to do this to be able to manipulate dates in the application but also to store them in a database using Opaleye or Esqueleto.

I have this:

import Data.Time
import Data.Time.Format

data User = User
  { userId    :: Int
  , name      :: Text
  , loginDate :: Day
  } deriving (Eq, Show)


currentDay :: Day
currentDay = utctDay <$> getCurrentTime ???

users :: [User]
users = [ User 1 "A" currentDay
        , User 2 "B" currentDay
        ]

But the type of currentDay is IO Day. How can I get it as Day only? I am guessing that is not possible without breaking type safety but I am not sure.

I could change the type of loginDate to IO Day but then I wouldn't be able to derive Eq and Show and thus be unable to use deriveJSON while using Servant. If I change the type of currentDay to IO Day and users to IO [User] then I cannot use Servant types.

Upvotes: 0

Views: 222

Answers (1)

ErikR
ErikR

Reputation: 52039

currentDay (as well as getCurrentTime) is an IO-action. You have to execute it in the IO-monad to retrieve the current day.

You code should look like:

currentDay :: IO Day
currentDay = utctDay <$> getCurrentTime

createUsers :: IO [User]
createUsers = do
  today <- currentDay
  return [ User 1 "A" today, User 2 "B" today ]

Upvotes: 1

Related Questions