gpt4 book ai didi

haskell - 在 Web.Scotty 中使用 StateT

转载 作者:行者123 更新时间:2023-12-04 08:07:23 26 4
gpt4 key购买 nike

我正在尝试制作一个愚蠢的网络服务器,将数据存储为 State .我正在使用 Web.Scotty . I've used ReaderT before with scotty to access config ,但遵循相同的方法在这里不起作用。它重置每个请求的状态。

我想在程序启动时设置初始状态,然后在程序的整个生命周期中保持相同的状态。

我怎样才能使这项工作? (以下每个请求都会创建一个新状态)

{-# LANGUAGE OverloadedStrings #-}
import Web.Scotty.Trans
import Control.Monad.State (StateT, evalStateT, lift)
import qualified Control.Monad.State as S
import Data.Text.Lazy (Text)

main :: IO ()
main = do
let runner = flip evalStateT "message"
scottyT 3000 runner runner routes

routes :: ScottyT Text (StateT Text IO) ()
routes = do

get "/data" $ do
val <- lift S.get
text val

put "/data/:val" $ do
val <- param "val"
lift $ S.put val
text val

最佳答案

您看到的行为绝对是预期的行为:
注意 documentation for scottyT 中第三个参数的注释:

-> (m Response -> IO Response) -- Run monad m into IO, called at each action.



您可以做的是将状态存储在 StateT 之外。 monad,以便您可以在每个操作的处理程序中恢复它。我能想到的最天真的方法是这样的:
main :: IO ()
main = do
let s0 = "message"
let transform = flip evalStateT s0
runner <- restartableStateT s0
scottyT 3000 transform runner routes

restartableStateT :: s -> IO (StateT s IO a -> IO a)
restartableStateT s0 = do
r <- newIORef s0
return $ \act -> do
s <- readIORef r
(x, s') <- runStateT act s
atomicModifyIORef' r $ const (s', x)

但这并没有真正解决如果两个请求同时进入会发生什么,它只是“最后一个完成胜利”。

关于haskell - 在 Web.Scotty 中使用 StateT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27495381/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com