2010-01-21 66 views
10

我需要一些Int s作爲種子隨機數生成,所以我想使用系統時間作爲種子的舊技巧。如何使用Data.Time.Clock在Haskell中獲取系統時間?

於是,我就用Data.Time包,我設法做到以下幾點:

import Data.Time.Clock 

time = getCurrentTime >>= return . utctDayTime 

當我運行時我得到的東西,如:

Prelude Data.Time.Clock> time 
55712.00536s 

類型的timeIO DiffTime。我期望看到一個IO Something類型,因爲這取決於程序外部的東西。所以我有兩個問題:

a)是否有可能以某種方式展開IO並獲取底層DiffTime值?

b)如何將DiffTime轉換爲一個整數值並以秒爲單位?有一個功能secondsToDiffTime,但我找不到它的逆。

回答

15

是否有可能以某種方式解開的IO,並獲得潛在DiffTime價值?

是。關於monads有幾十個教程可以解釋如何。他們都基於這樣的想法:你寫函數需要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) 
    } 

欲瞭解更多信息,請參閱monad上的許多優秀tutoral之一。

+0

爲了簡單起見,特別是對初學者,你可以省略括號作爲回報。 f和whow空格式do語法? – codebliss 2010-01-22 03:03:23

+4

@codebliss:對於一個初學者,我想讓事情變得非常明確,所以不需要讀者理解運算符優先級或佈局的細節 – 2010-01-22 10:35:36

+1

因爲每個monad都是一個函數,所以你也可以做'f <$>時間'。 IMO看起來很不錯。 – 2013-02-19 06:54:52

7

a)當然有可能得到DiffTime值;否則,這個功能將是毫無意義的。你需要閱讀monads。 Real World Haskell的This chapterthe next有很好的介紹。

b)docs for DiffTime表示它是Real類的一個實例,即它可以被視爲一個實數,在這個例子中是秒數。將其轉換爲秒因此鏈接轉換功能的一個簡單的問題:

diffTimeToSeconds :: DiffTime -> Integer 
diffTimeToSeconds = floor . toRational 
+0

但是,這樣就會失去皮秒。我通常會截斷。 (來自整體精度*)。 toRational。 utctDayTime',它給你的皮秒數。 (對於播種一個RNG,使用這個值可以讓你每秒有多個初始狀態,這在很多應用中都很重要。) – jrockway 2010-01-24 07:08:05

+0

(哦,精度= 10000000000000) – jrockway 2010-01-24 07:16:54

7

如果您計劃使用標準System.Random模塊隨機數生成,那麼有沒有已經與你初始化的時間相關的種子發電機:你可以通過調用getStdGen :: IO StdGen得到它。 (當然,你仍然需要回答你的問題的第(a)部分來使用結果。)

0

這個函數並不是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