Safe Haskell | Safe-Inferred |
---|---|
Language | GHC2021 |
A haskell library for representing:
- web pages, as (composable) collections of Html, Css and JS text.
- things that have a tied together represention in Haskell and in the DOM, where things can have shared sub-components.
- websocket & server communication protocols.
See app/examples.hs and Examples
for usage.
Synopsis
- data RepF r a = Rep {
- rep :: r
- make :: HashMap ByteString ByteString -> (HashMap ByteString ByteString, Either ByteString a)
- type Rep a = RepF Markup a
- oneRep :: Monad m => Rep a -> (Rep a -> HashMap ByteString ByteString -> m ()) -> StateT (HashMap ByteString ByteString) m (HashMap ByteString ByteString, Either ByteString a)
- newtype SharedRepF m r a = SharedRep {
- unshare :: StateT (Int, HashMap ByteString ByteString) m (RepF r a)
- type SharedRep m a = SharedRepF m Markup a
- runOnce :: Monad m => SharedRep m a -> (Markup -> HashMap ByteString ByteString -> m ()) -> m (HashMap ByteString ByteString, Either ByteString a)
- zeroState :: Monad m => SharedRep m a -> m (Markup, (HashMap ByteString ByteString, Either ByteString a))
- register :: Monad m => (ByteString -> Either ByteString a) -> (a -> ByteString) -> (ByteString -> a -> r) -> a -> SharedRepF m r a
- genName :: MonadState Int m => m ByteString
- genNamePre :: MonadState Int m => ByteString -> m ByteString
- data Page = Page {}
- data PageConfig = PageConfig {}
- defaultPageConfig :: FilePath -> PageConfig
- data Concerns a = Concerns {
- cssConcern :: a
- jsConcern :: a
- htmlConcern :: a
- suffixes :: Concerns FilePath
- concernNames :: FilePath -> FilePath -> Concerns FilePath
- data PageConcerns
- data PageStructure
- data RenderStyle
- newtype Css = Css {}
- renderCss :: RenderStyle -> Css -> ByteString
- cssColorScheme :: Css
- newtype Js = Js {}
- onLoad :: Js -> Js
- module Web.Rep.SharedReps
- module Web.Rep.Render
- module Web.Rep.Server
- module Web.Rep.Socket
- module Web.Rep.Html
- module Web.Rep.Html.Input
- module Web.Rep.Bootstrap
- data HashMap k v
Shared Representation
Information contained in a web page can usually be considered to be isomorphic to a map of named values - a HashMap
. This is especially true when considering a differential of information contained in a web page. Looking at a page from the outside, it often looks like a streaming differential of a hashmap.
RepF consists of an underlying value being represented, and, given a hashmap state, a way to produce a representation of the underlying value (or error), in another domain, together with the potential to alter the hashmap state.
Rep | |
|
oneRep :: Monad m => Rep a -> (Rep a -> HashMap ByteString ByteString -> m ()) -> StateT (HashMap ByteString ByteString) m (HashMap ByteString ByteString, Either ByteString a) Source #
stateful result of one step, given a RepF
, and a monadic action.
Useful for testing and for initialising a page.
newtype SharedRepF m r a Source #
Driven by the architecture of the DOM, web page components are compositional, and tree-like, where components are often composed of other components, and values are thus shared across components.
This is sometimes referred to as "observable sharing". See data-reify as another library that reifies this (pun intended), and provided the initial inspiration for this implementation.
unshare should only be run once, which is a terrible flaw that might be fixed by linear types.
SharedRep | |
|
Instances
runOnce :: Monad m => SharedRep m a -> (Markup -> HashMap ByteString ByteString -> m ()) -> m (HashMap ByteString ByteString, Either ByteString a) Source #
Compute the initial state of a SharedRep and then run an action once (see tests).
zeroState :: Monad m => SharedRep m a -> m (Markup, (HashMap ByteString ByteString, Either ByteString a)) Source #
compute the initial state of a SharedRep (testing)
:: Monad m | |
=> (ByteString -> Either ByteString a) | Parser |
-> (a -> ByteString) | Printer |
-> (ByteString -> a -> r) | create initial object from name and initial value |
-> a | initial value |
-> SharedRepF m r a |
Create a sharedRep
genName :: MonadState Int m => m ByteString Source #
name supply for elements of a SharedRepF
genNamePre :: MonadState Int m => ByteString -> m ByteString Source #
sometimes a number doesn't work properly in html (or js???), and an alpha prefix seems to help
Web Rep Components
Components of a web page.
A web page can take many forms but still have the same underlying representation. For example, CSS can be linked to in a separate file, or can be inline within html, but still be the same css and have the same expected external effect. A Page represents the practical components of what makes up a static snapshot of a web page.
Instances
data PageConfig Source #
Configuration options when rendering a Page
.
PageConfig | |
|
Instances
defaultPageConfig :: FilePath -> PageConfig Source #
Default configuration is inline ecma and css, separate html header and body, minified code, with the suggested filename prefix.
A web page typically is composed of some css, javascript and html.
Concerns
abstracts this structural feature of a web page.
Concerns | |
|
Instances
concernNames :: FilePath -> FilePath -> Concerns FilePath Source #
Create filenames for each Concern element.
data PageConcerns Source #
Is the rendering to include all Concerns
(typically in a html file) or be separated (tyypically into separate files and linked in the html file)?
Instances
Generic PageConcerns Source # | |
Defined in Web.Rep.Page type Rep PageConcerns :: Type -> Type # from :: PageConcerns -> Rep PageConcerns x # to :: Rep PageConcerns x -> PageConcerns # | |
Show PageConcerns Source # | |
Defined in Web.Rep.Page showsPrec :: Int -> PageConcerns -> ShowS # show :: PageConcerns -> String # showList :: [PageConcerns] -> ShowS # | |
Eq PageConcerns Source # | |
Defined in Web.Rep.Page (==) :: PageConcerns -> PageConcerns -> Bool # (/=) :: PageConcerns -> PageConcerns -> Bool # | |
type Rep PageConcerns Source # | |
data PageStructure Source #
Various ways that a Html file can be structured.
Instances
Generic PageStructure Source # | |
Defined in Web.Rep.Page type Rep PageStructure :: Type -> Type # from :: PageStructure -> Rep PageStructure x # to :: Rep PageStructure x -> PageStructure # | |
Show PageStructure Source # | |
Defined in Web.Rep.Page showsPrec :: Int -> PageStructure -> ShowS # show :: PageStructure -> String # showList :: [PageStructure] -> ShowS # | |
Eq PageStructure Source # | |
Defined in Web.Rep.Page (==) :: PageStructure -> PageStructure -> Bool # (/=) :: PageStructure -> PageStructure -> Bool # | |
type Rep PageStructure Source # | |
Defined in Web.Rep.Page type Rep PageStructure = D1 ('MetaData "PageStructure" "Web.Rep.Page" "web-rep-0.12.1.0-mljk32nWcoKJWZerP610X" 'False) (C1 ('MetaCons "HeaderBody" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "Headless" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Snippet" 'PrefixI 'False) (U1 :: Type -> Type))) |
data RenderStyle #
Indented 0
puts newlines in between the tags.
Instances
Generic RenderStyle | |
Defined in MarkupParse type Rep RenderStyle :: Type -> Type # from :: RenderStyle -> Rep RenderStyle x # to :: Rep RenderStyle x -> RenderStyle # | |
Show RenderStyle | |
Defined in MarkupParse showsPrec :: Int -> RenderStyle -> ShowS # show :: RenderStyle -> String # showList :: [RenderStyle] -> ShowS # | |
Eq RenderStyle | |
Defined in MarkupParse (==) :: RenderStyle -> RenderStyle -> Bool # (/=) :: RenderStyle -> RenderStyle -> Bool # | |
type Rep RenderStyle | |
Defined in MarkupParse type Rep RenderStyle = D1 ('MetaData "RenderStyle" "MarkupParse" "markup-parse-0.1.1-SEKTGv2jE1TKgMeR4lVM" 'False) (C1 ('MetaCons "Compact" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Indented" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int))) |
Css
css as a string.
Instances
Monoid Css Source # | |
Semigroup Css Source # | |
Generic Css Source # | |
Show Css Source # | |
Eq Css Source # | |
type Rep Css Source # | |
Defined in Web.Rep.Page type Rep Css = D1 ('MetaData "Css" "Web.Rep.Page" "web-rep-0.12.1.0-mljk32nWcoKJWZerP610X" 'True) (C1 ('MetaCons "Css" 'PrefixI 'True) (S1 ('MetaSel ('Just "cssByteString") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 ByteString))) |
renderCss :: RenderStyle -> Css -> ByteString Source #
Render Css
as text.
cssColorScheme :: Css Source #
Css snippet for reponsiveness to preferred color-scheme.
JS
Javascript as string
Instances
Monoid Js Source # | |
Semigroup Js Source # | |
Generic Js Source # | |
Show Js Source # | |
Eq Js Source # | |
type Rep Js Source # | |
Defined in Web.Rep.Page type Rep Js = D1 ('MetaData "Js" "Web.Rep.Page" "web-rep-0.12.1.0-mljk32nWcoKJWZerP610X" 'True) (C1 ('MetaCons "Js" 'PrefixI 'True) (S1 ('MetaSel ('Just "jsByteString") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 ByteString))) |
re-export modules
module Web.Rep.SharedReps
module Web.Rep.Render
module Web.Rep.Server
module Web.Rep.Socket
module Web.Rep.Html
module Web.Rep.Html.Input
module Web.Rep.Bootstrap
re-exports
A map from keys to values. A map cannot contain duplicate keys; each key can map to at most one value.
Instances
Bifoldable HashMap | Since: unordered-containers-0.2.11 |
Eq2 HashMap | |
Ord2 HashMap | |
Defined in Data.HashMap.Internal | |
Show2 HashMap | |
NFData2 HashMap | Since: unordered-containers-0.2.14.0 |
Defined in Data.HashMap.Internal | |
Hashable2 HashMap | |
Defined in Data.HashMap.Internal | |
(Lift k, Lift v) => Lift (HashMap k v :: Type) | Since: unordered-containers-0.2.17.0 |
Foldable (HashMap k) | |
Defined in Data.HashMap.Internal fold :: Monoid m => HashMap k m -> m # foldMap :: Monoid m => (a -> m) -> HashMap k a -> m # foldMap' :: Monoid m => (a -> m) -> HashMap k a -> m # foldr :: (a -> b -> b) -> b -> HashMap k a -> b # foldr' :: (a -> b -> b) -> b -> HashMap k a -> b # foldl :: (b -> a -> b) -> b -> HashMap k a -> b # foldl' :: (b -> a -> b) -> b -> HashMap k a -> b # foldr1 :: (a -> a -> a) -> HashMap k a -> a # foldl1 :: (a -> a -> a) -> HashMap k a -> a # toList :: HashMap k a -> [a] # length :: HashMap k a -> Int # elem :: Eq a => a -> HashMap k a -> Bool # maximum :: Ord a => HashMap k a -> a # minimum :: Ord a => HashMap k a -> a # | |
Eq k => Eq1 (HashMap k) | |
Ord k => Ord1 (HashMap k) | |
Defined in Data.HashMap.Internal | |
(Eq k, Hashable k, Read k) => Read1 (HashMap k) | |
Defined in Data.HashMap.Internal | |
Show k => Show1 (HashMap k) | |
Traversable (HashMap k) | |
Functor (HashMap k) | |
NFData k => NFData1 (HashMap k) | Since: unordered-containers-0.2.14.0 |
Defined in Data.HashMap.Internal | |
Hashable k => Hashable1 (HashMap k) | |
Defined in Data.HashMap.Internal | |
(Data k, Data v, Eq k, Hashable k) => Data (HashMap k v) | |
Defined in Data.HashMap.Internal gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> HashMap k v -> c (HashMap k v) # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (HashMap k v) # toConstr :: HashMap k v -> Constr # dataTypeOf :: HashMap k v -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (HashMap k v)) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (HashMap k v)) # gmapT :: (forall b. Data b => b -> b) -> HashMap k v -> HashMap k v # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> HashMap k v -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> HashMap k v -> r # gmapQ :: (forall d. Data d => d -> u) -> HashMap k v -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> HashMap k v -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> HashMap k v -> m (HashMap k v) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> HashMap k v -> m (HashMap k v) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> HashMap k v -> m (HashMap k v) # | |
(Eq k, Hashable k) => Monoid (HashMap k v) | If a key occurs in both maps, the mapping from the first will be the mapping in the result. Examples
|
(Eq k, Hashable k) => Semigroup (HashMap k v) | If a key occurs in both maps, the mapping from the first will be the mapping in the result. Examples
|
(Eq k, Hashable k) => IsList (HashMap k v) | |
(Eq k, Hashable k, Read k, Read e) => Read (HashMap k e) | |
(Show k, Show v) => Show (HashMap k v) | |
(NFData k, NFData v) => NFData (HashMap k v) | |
Defined in Data.HashMap.Internal | |
(Eq k, Eq v) => Eq (HashMap k v) | Note that, in the presence of hash collisions, equal
In general, the lack of substitutivity can be observed with any function that depends on the key ordering, such as folds and traversals. |
(Ord k, Ord v) => Ord (HashMap k v) | The ordering is total and consistent with the |
Defined in Data.HashMap.Internal | |
(Hashable k, Hashable v) => Hashable (HashMap k v) | |
Defined in Data.HashMap.Internal | |
type Item (HashMap k v) | |
Defined in Data.HashMap.Internal |