1

我有一个简单的小 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

解决这个问题的最优雅的方法是什么?

4

1 回答 1

1

当我写这个问题时,我发现了一个在Happstack crash course (templates)中有效的解决方案。

在返回类型为的路线中,ServerPart Response您可以使用liftIOmonad 转换器来执行 IO 操作。有一个方便的函数调用with从一个元组的输入中randomRIO生成一个随机数,其中两个s 作为范围,如下所示:IntInt

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

于 2013-06-15T18:07:51.947 回答