[英]How can I use an `IO String` inside a Spock request handler?
我有以下函數生成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
-block產生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 <> "!") }
如何在Spock get請求處理程序中使用我的IO
-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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.