1

Haskell を使い始めたばかりで、基本的な「エコー」REST サーバーに問題があります。

Spock は REST サーバーの良い出発点のように見えました。私は State モナドの基本を理解しましたrunStateが、spock コードの周りに a を配置する方法を理解するのに問題があります。

これが私がこれまでに得たコードです。

{-# 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"
4

1 に答える 1

2

restartableStateTわかりましたので、例のハックのバージョンを次に示します。

{-# 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「状態」を保存する単一のグローバルを作成します。にrunner渡されたは、 this から状態を取得し、計算を実行し、結果の状態を に戻すことで、spockT任意の計算を実行できます。StateT String IOIORefIORef

並行性の話がないため、これは必ずしも良い考えではないことを他の回答から繰り返したいと思います。たとえば、STM を使用することで紙に書き留めることができると思いますが、.

于 2015-08-12T07:36:26.530 に答える