unitym (empty) → 0.1.0.0
raw patch · 5 files changed
+140/−0 lines, 5 filesdep +basedep +textdep +transformerssetup-changed
Dependencies added: base, text, transformers
Files
- LICENSE +30/−0
- README.md +0/−0
- Setup.hs +2/−0
- src/Network/UnityM.hs +84/−0
- unitym.cabal +24/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Brian (c) 2017++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Author name here nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/Network/UnityM.hs view
@@ -0,0 +1,84 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE UndecidableInstances #-}++{- |+Module : Network.UnityM+Description : The Unity Monad- share code between Yesod and Servant, etc.+Copyright : (c) Brian Hurt, 2017+License : BSD3+Maintainer : bhurt42@gmail.com+Stability : experimental+Portability : Haskell++One of the nice things about WAI is that it allows us to combine multiple+different server frameworks in a single web server- allowing us to use+(for example) Yesod to develop the server-side rendered HTML part of the+website, and Servant to develop the REST API part. But this gives rise+to a desire to share code between the different frameworks. This is+where UnityM comes in.++UnityM is a type class for monad transformer stacks for web servers.+The assumption, in addition to being in some monad, is that we are+responding to some HTTP request, and can thus assume three things:++1. That we have read-only access to some global environment data,+generally a structure of some sort.++2. That the containing framework will catch all exceptions and+convert them into 500 (internal server error) status codes. And that+thus the low level code does not have to capture and handle exceptions,+and that a workable way to return 500 would be to just throw an exception.++3. That we have the ability to "short-circuit" the evaluation on+errors, and return 403 (permission denied) status codes from+the request.++The type class is a multi-parameter type class, with the first parameter+being the type of the environment variable that can be gotten. This allows+code to constrain this type with further type class constaints, and thus+work with multiple different environments, for example:++> class HasFoo a where+> getFoo :: a -> Foo+>+> bar :: (Monad m, HasFoo c, UnityM c m) => Something -> m Whatever+> bar x = do+> myFoo <- getFoo <$> getContext+> ...++Note that this type class assumes the code is "low-level", away from the+web request- buisness logic, database access, etc. And thus a rich+API for different status responses is not needed. Only two error results+are supported- the generic 500 Internal Server error, and the 403 Permission+Denied error. The second is only supported so that access grants can+be generalized. Error checking code that needs different status results+should be written in a framework-specific way.++The different implementations of the unity monad are in separate projects,+so you don't get unnecessary dependencies.++-}+module Network.UnityM where++ import Control.Monad.Trans.Class+ import Data.Text (Text)++ {- | The Unity Monad type class.++ For code that executes in multiple different web contexts.+ -}+ class UnityM c m | m -> c where+ {- | Get the context, the global read-only data object -}+ getContext :: m c+ {- | Short circuit the request with a 403 (Forbidden) status. -}+ permissionDenied :: Text -> m a++ {- | Support monad transformers on top of a Unity monad. -}+ instance {-# OVERLAPPABLE #-} (Monad m, UnityM c m, MonadTrans t) =>+ UnityM c (t m)+ where+ getContext = lift getContext+ permissionDenied = lift . permissionDenied+
+ unitym.cabal view
@@ -0,0 +1,24 @@+name: unitym+version: 0.1.0.0+synopsis: Initial project template from stack+description: Please see README.md+homepage: https://github.com/githubuser/unitym#readme+license: BSD3+license-file: LICENSE+author: Author name here+maintainer: example@example.com+copyright: 2017 Author name here+category: Web+build-type: Simple+extra-source-files: README.md+cabal-version: >=1.10++library+ hs-source-dirs: src+ exposed-modules: Network.UnityM+ build-depends: base >= 4.7 && < 5+ , text >= 1.2 && < 1.3+ , transformers >= 0.5 && < 0.6+ default-language: Haskell2010+ ghc-options: -W -Wall -O2+