Как получить системное время в Haskell, используя Data.Time.Clock? - PullRequest
11 голосов
/ 21 января 2010

Мне нужно несколько 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?

б) Как преобразовать DiffTime в целое число со значением в секундах? Есть функция secondsToDiffTime, но я не могу найти ее обратную.

Ответы [ 4 ]

17 голосов
/ 21 января 2010

Можно ли как-то развернуть 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)
   }

Более подробную информацию можно получить у одного из множества прекрасных учителей по монадам.

8 голосов
/ 21 января 2010

Если вы планируете использовать стандартный модуль System.Random для генерации случайных чисел, то для вас уже есть генератор с инициализацией зависящего от времени начального числа: вы можете получить его, вызвав getStdGen :: IO StdGen. (Конечно, вам все еще нужен ответ на часть (а) вашего вопроса, чтобы использовать результат.)

8 голосов
/ 21 января 2010

а) Конечно, можно получить значение DiffTime; в противном случае эта функция была бы довольно бессмысленной. Вам нужно будет прочитать о монады. Эта глава и следующего из Real World на Haskell содержит хорошее введение.

b) Документы для DiffTime говорят, что это экземпляр класса Real, т. Е. Его можно рассматривать как действительное число, в данном случае это количество секунд. Таким образом, преобразование его в секунды является простым делом объединения функций преобразования:

diffTimeToSeconds :: DiffTime -> Integer
diffTimeToSeconds = floor . toRational
0 голосов
/ 16 июня 2014

Эта функция не совсем то, что запрашивает 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
...