Created
August 3, 2015 13:40
-
-
Save codedmart/9a473ab59a05be8a467b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {-# LANGUAGE CPP #-} | |
| {-# LANGUAGE DeriveDataTypeable #-} | |
| {-# LANGUAGE FlexibleInstances #-} | |
| {-# LANGUAGE FunctionalDependencies #-} | |
| {-# LANGUAGE MultiParamTypeClasses #-} | |
| {-# LANGUAGE RankNTypes #-} | |
| {-# LANGUAGE ScopedTypeVariables #-} | |
| {-# LANGUAGE TypeFamilies #-} | |
| {-# LANGUAGE TypeOperators #-} | |
| {-# LANGUAGE UndecidableInstances #-} | |
| module Servant.Server.Internal.Enter where | |
| #if !MIN_VERSION_base(4,8,0) | |
| import Control.Applicative | |
| #endif | |
| import qualified Control.Category as C | |
| #if MIN_VERSION_mtl(2,2,1) | |
| import Control.Monad.Except | |
| #endif | |
| import Control.Monad.Identity | |
| import Control.Monad.Morph | |
| import Control.Monad.Reader | |
| import qualified Control.Monad.State.Lazy as LState | |
| import qualified Control.Monad.State.Strict as SState | |
| #if MIN_VERSION_mtl(2,2,1) | |
| import Control.Monad.Trans.Either | |
| #endif | |
| import qualified Control.Monad.Writer.Lazy as LWriter | |
| import qualified Control.Monad.Writer.Strict as SWriter | |
| import Data.Typeable | |
| import Servant.API | |
| class Enter typ arg ret | typ arg -> ret, typ ret -> arg where | |
| enter :: arg -> typ -> ret | |
| -- ** Servant combinators | |
| instance ( Enter typ1 arg1 ret1, Enter typ2 arg2 ret2 | |
| , arg1 ~ arg2 | |
| ) => Enter (typ1 :<|> typ2) arg1 (ret1 :<|> ret2) where | |
| enter e (a :<|> b) = enter e a :<|> enter e b | |
| instance (Enter b arg ret) => Enter (a -> b) arg (a -> ret) where | |
| enter arg f a = enter arg (f a) | |
| -- ** Useful instances | |
| -- | A natural transformation from @m@ to @n@. Used to `enter` particular | |
| -- datatypes. | |
| newtype m :~> n = Nat { unNat :: forall a. m a -> n a} deriving Typeable | |
| instance C.Category (:~>) where | |
| id = Nat id | |
| Nat f . Nat g = Nat (f . g) | |
| instance Enter (Raw m a) (m :~> n) (Raw n a) where | |
| enter _ (Raw a) = Raw a | |
| instance Enter (m a) (m :~> n) (n a) where | |
| enter (Nat f) = f | |
| -- | Like `lift`. | |
| liftNat :: (Control.Monad.Morph.MonadTrans t, Monad m) => m :~> t m | |
| liftNat = Nat Control.Monad.Morph.lift | |
| runReaderTNat :: r -> (ReaderT r m :~> m) | |
| runReaderTNat a = Nat (`runReaderT` a) | |
| evalStateTLNat :: Monad m => s -> (LState.StateT s m :~> m) | |
| evalStateTLNat a = Nat (`LState.evalStateT` a) | |
| evalStateTSNat :: Monad m => s -> (SState.StateT s m :~> m) | |
| evalStateTSNat a = Nat (`SState.evalStateT` a) | |
| -- | Log the contents of `SWriter.WriterT` with the function provided as the | |
| -- first argument, and return the value of the @WriterT@ computation | |
| logWriterTSNat :: MonadIO m => (w -> IO ()) -> (SWriter.WriterT w m :~> m) | |
| logWriterTSNat logger = Nat $ \x -> do | |
| (a, w) <- SWriter.runWriterT x | |
| liftIO $ logger w | |
| return a | |
| -- | Like `logWriterTSNat`, but for strict @WriterT@. | |
| logWriterTLNat :: MonadIO m => (w -> IO ()) -> (LWriter.WriterT w m :~> m) | |
| logWriterTLNat logger = Nat $ \x -> do | |
| (a, w) <- LWriter.runWriterT x | |
| liftIO $ logger w | |
| return a | |
| #if MIN_VERSION_mtl(2,2,1) | |
| fromExceptT :: ExceptT e m :~> EitherT e m | |
| fromExceptT = Nat $ \x -> EitherT $ runExceptT x | |
| #endif | |
| -- | Like @mmorph@'s `hoist`. | |
| hoistNat :: (MFunctor t, Monad m) => (m :~> n) -> (t m :~> t n) | |
| hoistNat (Nat n) = Nat $ hoist n | |
| -- | Like @mmorph@'s `embed`. | |
| embedNat :: (MMonad t, Monad n) => (m :~> t n) -> (t m :~> t n) | |
| embedNat (Nat n) = Nat $ embed n | |
| -- | Like @mmorph@'s `squash`. | |
| squashNat :: (Monad m, MMonad t) => t (t m) :~> t m | |
| squashNat = Nat squash | |
| -- | Like @mmorph@'s `generalize`. | |
| generalizeNat :: Applicative m => Identity :~> m | |
| generalizeNat = Nat (pure . runIdentity) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| src/Servant/Server/Internal/Enter.hs:55:10: | |
| Functional dependencies conflict between instance declarations: | |
| instance Enter (Raw m a) (m :~> n) (Raw n a) | |
| -- Defined at src/Servant/Server/Internal/Enter.hs:55:10 | |
| instance Enter (m a) (m :~> n) (n a) | |
| -- Defined at src/Servant/Server/Internal/Enter.hs:58:10 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {-# LANGUAGE DeriveDataTypeable #-} | |
| {-# LANGUAGE KindSignatures #-} | |
| {-# OPTIONS_HADDOCK not-home #-} | |
| module Servant.API.Raw where | |
| import Data.Typeable (Typeable) | |
| -- | Endpoint for plugging in your own Wai 'Application's. | |
| -- | |
| -- The given 'Application' will get the request as received by the server, potentially with | |
| -- a modified (stripped) 'pathInfo' if the 'Application' is being routed with 'Servant.API.Sub.:>'. | |
| -- | |
| -- In addition to just letting you plug in your existing WAI 'Application's, | |
| -- this can also be used with 'Servant.Utils.StaticFiles.serveDirectory' to serve | |
| -- static files stored in a particular directory on your filesystem | |
| newtype Raw (m :: * -> *) a = Raw { | |
| unRaw :: a | |
| } | |
| deriving (Eq, Show, Typeable) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment