2016-07-04 6 views
1

나는 정의의 종 처리기사용자 지정 서버 핸들러에서 HTTP 상태로 응답하는 방법은 무엇입니까?

type ServiceSet = TVar (M.Map String [MicroService]) 
type LocalHandler = ReaderT ServiceSet IO 

을 생성하지만 난 다음 함수에서 클라이언트에 발견 된 404-없는 상태 코드를 응답 할 수있는 방법을 찾지 못했습니다 :

getService :: String -> LocalHandler MicroService 
getService sn = do 
    tvar <- ask 
    ms <- liftIO $ do 
    sl <- atomically $ do 
     sm <- readTVar tvar 
     return $ case M.lookup sn sm of 
     Nothing -> [] 
     Just sl -> sl 
    let n = length sl 
    i <- randomRIO (0, n - 1) 
    return $ if n == 0 
     then Nothing 
     else Just . head . drop i $ sl 
    case ms of 
    Nothing -> ??? -- throwError err404 
    Just ms' -> return ms' 

(404 개)의 상태를 전송하는 방법 ???에 코드가 있습니까?

답변

3

모나드 변환 스택에 ExceptT을 추가해야합니다. 지금은 단지 ReaderT으로, 던져진 오류의 개념을 인코딩 할 방법이 없습니다. 당신이 다음 throwError err404, 종 잡을와 HTTP 404 천연 변환 ExceptT ServantErr . ReaderT (TVar ...) :~> ExceptT ServantErr을 반환하는 데 사용할 수 있습니다 ExceptT ServantErr . ReaderT (TVar ...)

{-# LANGUAGE DataKinds  #-} 
{-# LANGUAGE TypeOperators #-} 

module Lib where 

import Control.Monad.Except 
import Control.Monad.Reader 
import Data.Maybe 
import Data.Map 
import GHC.Conc 
import Prelude hiding (lookup) 
import Servant.API 
import Servant.Server 
import System.Random 

type API = 
    Capture "name" String :> Get '[JSON] Int 

type World = 
    TVar (Map String [Int]) 

type Effects = 
    ExceptT ServantErr (ReaderT World IO) 

server :: World -> Server API 
server world = 
    enter (Nat transform) get 
    where 
    transform :: Effects a -> ExceptT ServantErr IO a 
    transform (ExceptT foo) = 
     ExceptT $ runReaderT foo world 

get :: String -> Effects Int 
get sn = do 
    tvar <- ask 
    ms <- liftIO $ do 
    sl <- atomically $ do 
     sm <- readTVar tvar 
     return (fromMaybe [] (lookup sn sm)) 
    let n = length sl 
    i <- randomRIO (0, n - 1) 
    return $ if n == 0 
     then Nothing 
     else Just . head . drop i $ sl 
    case ms of 
    Nothing -> 
     throwError err404 
    Just ms' -> 
     return ms' 

는 포장을 푸는 독자 효과를 배출하기 위해 리 래핑해야합니다. 전체적으로 끔찍한 코드가 아닙니다.