Как получить системное время в Haskell с помощью Data.Time.Clock?
Мне нужно немного Int
использовать для генерации семян для случайных чисел, поэтому я хотел использовать старый трюк использования системного времени в качестве семени.
Итак, я попытался использовать пакет Data.Time, и мне удалось сделать следующее:
import Data.Time.Clock
time = getCurrentTime >>= return . utctDayTime
Когда я запускаю время, я получаю такие вещи, как:
Prelude Data.Time.Clock> time
55712.00536s
Тип time
- IO DiffTime
. Я ожидал увидеть тип IO Something
, поскольку это зависит от вещей, внешних по отношению к программе. Поэтому у меня есть два вопроса:
a) Можно ли каким-то образом развернуть IO и получить базовое значение DiffTime?
b) Как преобразовать DiffTime в целое число с его значением в секундах? Там функция secondsToDiffTime
, но я не мог найти ее обратную.
Ответы
Ответ 1
Можно ли как-то развернуть IO и получить базовое значение DiffTime?
Да. Есть несколько уроков по монадам, которые объясняют, как это сделать. Все они основаны на идее, что вы пишете функцию, которая принимает DiffTime
и что-то делает (скажем, возврат IO ()
) или просто возвращает Answer
. Поэтому, если у вас есть f :: DiffTime -> Answer
, вы пишете
time >>= \t -> return (f t)
который некоторые люди предпочитают писать
time >>= (return . f)
и если у вас есть continue :: DiffTime -> IO ()
, у вас есть
time >>= continue
Или вы можете предпочесть обозначение do
:
do { t <- time
; continue t -- or possibly return (f t)
}
Более подробно проконсультируйтесь с одним из многих прекрасных учителей на монадах.
Ответ 2
a) Конечно, можно получить значение DiffTime
; в противном случае эта функция была бы совершенно бессмысленной. Вам нужно будет прочитать о монадах. В этой главе и в следующем Real World Haskell есть хорошая введение.
b) docs для DiffTime
говорят, что это экземпляр класса Real
, то есть он может рассматриваться как реальный число, в этом случае количество секунд. Таким образом, преобразование его в считанные секунды является простым способом цепочки преобразования:
diffTimeToSeconds :: DiffTime -> Integer
diffTimeToSeconds = floor . toRational
Ответ 3
Если вы планируете использовать стандартный модуль System.Random
для генерации случайных чисел, то для вас уже есть генератор с инициализированным по времени семенами: вы можете получить его, вызвав getStdGen :: IO StdGen
. (Конечно, вам все равно нужен ответ на часть (а) вашего вопроса, чтобы использовать результат.)
Ответ 4
Эта функция не совсем то, что спрашивает OP. Но это полезно:
λ: import Data.Time.Clock
λ: let getSeconds = getCurrentTime >>= return . fromRational . toRational . utctDayTime
λ: :i getSeconds
getSeconds :: IO Double -- Defined at <interactive>:56:5
λ: getSeconds
57577.607162
λ: getSeconds
57578.902397
λ: getSeconds
57580.387334