我有一个简单的小Happstack应用程序,它显示一个带有电子邮件字段和随机问题字段的表单,以帮助打击垃圾邮件。要获取一个随机数,我在getStdGen
函数中使用main
并将其传递给我创建html的函数。问题是使用相同的StdGen
因此我的随机值不是随机的,除非我重新启动应用程序。
这是Main.hs
的样子:
{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}
module Main where
import Happstack.Lite
import qualified Pages.Contact as Contact
import System.Random
main :: IO ()
main = do
gen <- getStdGen
serve Nothing $ pages gen
pages :: StdGen -> ServerPart Response
pages g = msum
[ dir "contact" $ Contact.page g
... Other irrelevant pages
]
这是使用StdGen
来检索随机问题ID的函数:
getRandomQID :: StdGen -> Int
getRandomQID g =
let (rpercent, _) = random g :: (Float, StdGen)
rid = rpercent * questionsAmount
in round rid
questionsAmount :: (Num a) => a
questionsAmount = (fromIntegral . length) questions
解决此问题最优雅的方法是什么?
答案 0 :(得分:1)
在我写这个问题时,我找到了一个适用于Happstack crash course (templates)的解决方案。
在返回类型为ServerPart Response
的路由中,您可以使用liftIO
monad转换器来执行IO操作。有一个名为randomRIO
的方便函数,它从一个元组的输入生成一个随机Int
,其中两个Int
作为范围,如下所示:
page :: ServerPart Response
page = do
randID <- liftIO $ randomRIO (0, max)
... Code to generate response ...
where max = length questions
randomRIO
可以在System.Random
中找到,liftIO
可以在Control.Monad.Trans
中找到。