我需要一些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
,但我找不到它的逆。
答案 0 :(得分:16)
是否有可能以某种方式展开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上许多优秀的tutorals之一。
答案 1 :(得分:8)
a)当然可以获得DiffTime
值;否则,这个功能将毫无意义。你需要阅读monad。真实世界哈斯克尔的This chapter和the next有一个很好的介绍。
b)docs for DiffTime
表示它是Real
类的一个实例,即它可以被视为实数,在这种情况下是秒数。因此,将其转换为秒是链接转换函数的简单问题:
diffTimeToSeconds :: DiffTime -> Integer
diffTimeToSeconds = floor . toRational
答案 2 :(得分:8)
如果您计划使用标准System.Random
模块生成随机数,那么已经有一个生成器,其中为您初始化了一个与时间相关的种子:您可以通过调用getStdGen :: IO StdGen
来获取它。 (当然,您仍然需要回答问题的(a)部分来使用结果。)
答案 3 :(得分: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