renderable 0.0.0.1 → 0.0.0.2
raw patch · 2 files changed
+42/−6 lines, 2 files
Files
- renderable.cabal +1/−1
- src/Data/Renderable.hs +41/−5
renderable.cabal view
@@ -10,7 +10,7 @@ -- PVP summary: +-+------- breaking API changes -- | | +----- non-breaking API additions -- | | | +--- code changes with no API change-version: 0.0.0.1+version: 0.0.0.2 -- A short (one-line) description of the package. synopsis: Provides a nice API for rendering data types that change
src/Data/Renderable.hs view
@@ -1,6 +1,8 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-} module Data.Renderable where import Prelude hiding (lookup)@@ -15,8 +17,15 @@ import GHC.Stack ----------------------------------------------------------------------------------- Other Renderables+-- Decomposable Instances --------------------------------------------------------------------------------+-- | Any element is decomposable by returning a list consisting of itself.+instance Decomposable (Element m r t) m r t where+ decompose e = [e]+--------------------------------------------------------------------------------+-- Renderable Instances+--------------------------------------------------------------------------------+-- | Any Element is renderable by rendering its contained datatype. instance Renderable (Element m r t) where type RenderMonad (Element m r t) = m type RenderRsrc (Element m r t) = r@@ -25,6 +34,19 @@ nameOf (Element a) = "Element " ++ nameOf a composite (Element a) = composite a +-- | A tuple is renderable when it is a pairing of a transform and another+-- renderable datatype.+instance ( t ~ RenderTfrm a, Show t, Monoid t+ , Hashable a, Renderable a) => Renderable (t,a) where+ type RenderMonad (t,a) = RenderMonad a+ type RenderTfrm (t,a) = RenderTfrm a+ type RenderRsrc (t,a) = RenderRsrc a+ cache rz rs (_,a) = attachIfNeeded rz rs a+ nameOf (t,a) = "(" ++ show t ++ ", " ++ nameOf a ++ ")"+ composite (t,a) = map (fmap $ fmap (t <>)) $ composite a++-- | A Maybe is renderable by rendering the datatype contained in the Just+-- constructor or by rendering nothing. instance (Renderable a, Hashable a, Show a) => Renderable (Maybe a) where type RenderMonad (Maybe a) = RenderMonad a type RenderTfrm (Maybe a) = RenderTfrm a@@ -36,6 +58,8 @@ composite (Just a) = composite a composite _ = [] +-- | A list of renderable instances is renderable by rendering each+-- instance. instance (Renderable a, Hashable a) => Renderable [a] where type RenderMonad [a] = RenderMonad a type RenderTfrm [a] = RenderTfrm a@@ -104,6 +128,12 @@ Just rendering -> clean rendering return $ IM.delete k c --------------------------------------------------------------------------------+-- Decomposition+--------------------------------------------------------------------------------+-- | An instance of Decomposable can be broken down into a number of elements.+class Decomposable a m r t where+ decompose :: a -> [Element m r t]+-------------------------------------------------------------------------------- -- Element -------------------------------------------------------------------------------- instance Hashable (Element m r t) where@@ -115,9 +145,10 @@ instance Show (Element m r t) where show (Element a) = "Element{ " ++ show a ++ " }" --- | Element is a generic type that can be used to enclose homogenous--- instances of Renderable. 'm', 'r' and 't' are shared with all Renderable--- instances stored in an Element.+-- | Element is a generic existential type that can be used to enclose+-- instances of Renderable in order to contain them all in a heterogeneous list.+-- 'm', 'r' and 't' must be shared with all Renderable instances stored in+-- a heterogeneous list of Elements. data Element m r t where Element :: ( Monad m, Show a, Hashable a, Renderable a , m ~ RenderMonad a@@ -128,8 +159,13 @@ -- Renderable -------------------------------------------------------------------------------- class Renderable a where+ -- | The monad needed to render the datatype. In most cases this is+ -- probably IO. type RenderMonad a :: * -> *+ -- | The datatype that is used to transform renderings. type RenderTfrm a :: *+ -- | The datatype that holds cached resources that will be used to+ -- composite and render the datatype. type RenderRsrc a :: * -- | The name of a renderable datatype. This is mostly for debugging. nameOf :: a -> String@@ -158,7 +194,7 @@ -- | A composite is a representation of the entire rendered datatype. It is -- a flattened list of all the renderings (denoted by hash), along with--- that renderings local transformation. If a rendering is explicitly run+-- that rendering\'s local transformation. If a rendering is explicitly run -- by another rendering (as in a Renderable class definition) then the -- transformation for that rendering should be Nothing, which will keep -- 'renderComposite' from running that rendering in addition to the