我有以下函数生成1024的倍数的随机字符串:
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)
我想使用Spock将其暴露给Web,例如:
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
,而不是Spock的预期类型:
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 <> "!") }
如何IO
在Spock get请求处理程序中使用我的-driven随机字符串函数?
的ActionT
类型是的一个实例MonadIO
类型类.这意味着您可以使用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