簡體   English   中英

如何在Spock中使用持久性State monad?

[英]How do I use a persistent State monad with Spock?

我只是從haskell開始,而基本的“ echo” REST服務器卻遇到了問題。

Spock看起來像是REST服務器的理想起點,盡管我了解了State monad的基礎知識,但是在理解如何在spock代碼周圍放置runState遇到了問題。

這是到目前為止我得到的代碼。

{-# LANGUAGE OverloadedStrings #-}
module Main where

import Data.Monoid
import Web.Spock.Safe
import qualified Control.Monad.State as S

storeData :: String -> S.State String String
storeData val = do S.put val
                   return val

getData :: S.State String String
getData = do val <- S.get
             return val

main :: IO ()
main =
    runSpock 11350 $ spockT id $
    do get "store" $
           text "Would be a call to getData"

好的,這是您的示例的restartableStateT hack的版本:

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE Rank2Types #-}
module Main where

import Data.Monoid
import Data.String (fromString)
import Web.Spock.Safe
import qualified Control.Monad.State as S
import Data.IORef

storeData :: (Monad m) => String -> S.StateT String m String
storeData val = do S.put val
                   return val

getData :: (Monad m) => S.StateT String m String
getData = do val <- S.get
             return val

newtype RunStateT s m = RunStateT{ runStateT :: forall a. S.StateT s m a -> m a }

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

main :: IO ()
main = do
    runner <- restartableStateT "initial state"
    runSpock 11350 $ spockT (runStateT runner) $ do
        get "store" $ do
            cmd <- param "value"
            case cmd of
                Nothing -> do
                    old <- S.lift getData
                    text $ fromString old
                Just new -> do
                    S.lift $ storeData new
                    text "Stored."

像其他答案一樣,此IORef創建一個全局IORef來存儲“狀態”。 runner傳遞給spockT然后能夠運行任何StateT String IO通過此獲得國家計算IORef ,運行計算,並把結果狀態回IORef

我想從其他答案中重申,這不一定是一個好主意,因為它沒有並發的故事。 我想這可以通過使用STM來實現,但是...我認為您應該只使用數據庫來處理這種事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM