2016-02-13 84 views
3

我有以下功能產生的字符以1024的倍數隨機字符串:如何在Spock請求處理程序中使用`IO String`?

import System.Random 

rchars :: Int -> [IO Char] 
rchars n = map (\_ -> randomRIO ('a', 'z')) [n | n <- [0..n]] -- a wasteful "iteration"-like func 

rstr :: Int -> IO String 
rstr n = sequence $ rchars (1024 * n) 

我要揭露這個使用斯波克網絡,例如:

import Data.Monoid 
import Data.Text 
import Lib 
import Web.Spock.Safe 

main :: IO() 
main = 
    runSpock 8080 $ spockT id $ 
    do get root $ 
      redirect "/data/1" 
     get ("data" <//> var) $ \n -> 
      do 
      str <- rstr n 
      text ("boo:" <> str <> "!") 

但這不正確,作爲最do - 嵌段產生一個IO b0,而不是預期的類型從斯波克:

Couldn't match type ‘ActionT IO()’ with ‘IO b0’ 
Expected type: Int -> IO b0 
    Actual type: hvect-0.2.0.0:Data.HVect.HVectElim 
       '[Int] (ActionT IO()) 
The lambda expression ‘\ n -> ...’ has one argument, 
but its type ‘hvect-0.2.0.0:Data.HVect.HVectElim 
       '[Int] (ActionT IO())’ 
has none 
In the second argument of ‘($)’, namely 
    ‘\ n 
    -> do { str <- rstr n; 
      text ("boo:" <> str <> "!") }’ 
In a stmt of a 'do' block: 
    get ("data" <//> var) 
    $ \ n 
     -> do { str <- rstr n; 
       text ("boo:" <> str <> "!") } 

如何在Spock獲取請求處理程序中使用我的IO驅動的隨機字符串函數?

回答

6

ActionT類型是MonadIO typeclass的一個實例。這意味着您可以使用liftIO在此monad中執行IO操作。在你的情況下,你似乎需要liftIO $ rstr n而不是普通的rstr n

這說明什麼,我指的是:

import Control.Monad.IO.Class 
... 
main :: IO() 
main = 
    runSpock 8080 $ spockT id $ 
    do get root $ 
      redirect "/data/1" 
     get ("data" <//> var) $ \n -> 
      do 
      str <- liftIO $ rstr n 
      text $ pack str 
+0

從哪裏我導入'liftIO'? –

+0

http://haddock.stackage.org/lts-5.1/transformers-0.4.2.0/Control-Monad-IO-Class.html – arrowd

+0

在這裏你可以搜索模塊/功能:https://www.stackage.org /lts-5.1/hoogle?q=liftIO你甚至可以按照類型搜索! – arrowd