Safe Haskell | None |
---|---|
Language | Haskell2010 |
A haskell library for representing web pages.
This library is a collection of web page abstractions, together with a reimagining of suavemente.
I wanted to expose the server delivery mechanism, switch the streaming nature of the gap between a web page and a haskell server, and concentrate on getting a clean interface between pure haskell and the world that is a web page.
See app/examples.hs and Examples
for usage.
Synopsis
- data RepF r a = Rep {}
- type Rep a = RepF (Html ()) a
- oneRep :: (Monad m, MonadIO m) => Rep a -> (Rep a -> HashMap Text Text -> m ()) -> StateT (HashMap Text Text) m (HashMap Text Text, Either Text a)
- newtype SharedRepF m r a = SharedRep {}
- type SharedRep m a = SharedRepF m (Html ()) a
- data Element = Element {}
- runOnce :: Monad m => SharedRep m a -> (Html () -> HashMap Text Text -> m ()) -> m (HashMap Text Text, Either Text a)
- zeroState :: Monad m => SharedRep m a -> m (Html (), (HashMap Text Text, Either Text a))
- 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
- = HeaderBody
- | Headless
- | Snippet
- | Svg
- data PageRender
- type Css = StyleM ()
- data PageCss
- renderCss :: Css -> Text
- renderPageCss :: PageRender -> PageCss -> Text
- newtype JS = JS {}
- data PageJs
- = PageJs JS
- | PageJsText Text
- onLoad :: PageJs -> PageJs
- renderPageJs :: PageRender -> PageJs -> Text
- parseJs :: Text -> JS
- renderJs :: JS -> Text
- module Web.Page.SharedReps
- module Web.Page.Render
- module Web.Page.Server
- module Web.Page.Bridge
- module Web.Page.Html
- module Web.Page.Html.Input
- module Web.Page.Bootstrap
- module Web.Page.Mathjax
- module Data.Biapplicative
- module Data.Bifunctor
- module Text.InterpolatedString.Perl6
- module Control.Monad.Trans.State
- module Control.Applicative
- data Value
- finally :: IO a -> IO b -> IO a
- data HashMap k v
- fromList :: IsList l => [Item l] -> l
- void :: Functor f => f a -> f ()
- sequenceA_ :: (Foldable t, Applicative f) => t (f a) -> f ()
- data Text
- pack :: String -> Text
- unpack :: Text -> String
- toStrict :: Text -> Text
- bool :: a -> a -> Bool -> a
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.
oneRep :: (Monad m, MonadIO m) => Rep a -> (Rep a -> HashMap Text Text -> m ()) -> StateT (HashMap Text Text) m (HashMap Text Text, Either Text 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.
A key-value Text pair as the realistic datatype that zips across the interface between a page and haskell.
Instances
Eq Element Source # | |
Show Element Source # | |
Generic Element Source # | |
ToJSON Element Source # | |
Defined in Web.Page.Types | |
FromJSON Element Source # | |
type Rep Element Source # | |
Defined in Web.Page.Types type Rep Element = D1 (MetaData "Element" "Web.Page.Types" "web-rep-0.4.0-1tSvqwxGHX6oFAw2f4hvL" False) (C1 (MetaCons "Element" PrefixI True) (S1 (MetaSel (Just "element") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Text) :*: S1 (MetaSel (Just "value") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Text))) |
runOnce :: Monad m => SharedRep m a -> (Html () -> HashMap Text Text -> m ()) -> m (HashMap Text Text, Either Text a) Source #
Compute the initial state of a SharedRep and then run an action once (see tests).
zeroState :: Monad m => SharedRep m a -> m (Html (), (HashMap Text Text, Either Text a)) Source #
compute the initial state of a SharedRep (testing)
Web Page 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
Show Page Source # | |
Generic Page Source # | |
Semigroup Page Source # | |
Monoid Page Source # | |
type Rep Page Source # | |
Defined in Web.Page.Types type Rep Page = D1 (MetaData "Page" "Web.Page.Types" "web-rep-0.4.0-1tSvqwxGHX6oFAw2f4hvL" False) (C1 (MetaCons "Page" PrefixI True) ((S1 (MetaSel (Just "libsCss") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 [Html ()]) :*: (S1 (MetaSel (Just "libsJs") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 [Html ()]) :*: S1 (MetaSel (Just "cssBody") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 PageCss))) :*: ((S1 (MetaSel (Just "jsGlobal") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 PageJs) :*: S1 (MetaSel (Just "jsOnLoad") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 PageJs)) :*: (S1 (MetaSel (Just "htmlHeader") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Html ())) :*: S1 (MetaSel (Just "htmlBody") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Html ())))))) |
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
Eq PageConcerns Source # | |
Defined in Web.Page.Types (==) :: PageConcerns -> PageConcerns -> Bool # (/=) :: PageConcerns -> PageConcerns -> Bool # | |
Show PageConcerns Source # | |
Defined in Web.Page.Types showsPrec :: Int -> PageConcerns -> ShowS # show :: PageConcerns -> String # showList :: [PageConcerns] -> ShowS # | |
Generic PageConcerns Source # | |
Defined in Web.Page.Types type Rep PageConcerns :: Type -> Type # from :: PageConcerns -> Rep PageConcerns x # to :: Rep PageConcerns x -> PageConcerns # | |
type Rep PageConcerns Source # | |
data PageStructure Source #
Various ways that a Html file can be structured.
Instances
Eq PageStructure Source # | |
Defined in Web.Page.Types (==) :: PageStructure -> PageStructure -> Bool # (/=) :: PageStructure -> PageStructure -> Bool # | |
Show PageStructure Source # | |
Defined in Web.Page.Types showsPrec :: Int -> PageStructure -> ShowS # show :: PageStructure -> String # showList :: [PageStructure] -> ShowS # | |
Generic PageStructure Source # | |
Defined in Web.Page.Types type Rep PageStructure :: Type -> Type # from :: PageStructure -> Rep PageStructure x # to :: Rep PageStructure x -> PageStructure # | |
type Rep PageStructure Source # | |
Defined in Web.Page.Types type Rep PageStructure = D1 (MetaData "PageStructure" "Web.Page.Types" "web-rep-0.4.0-1tSvqwxGHX6oFAw2f4hvL" 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) :+: C1 (MetaCons "Svg" PrefixI False) (U1 :: Type -> Type))) |
data PageRender Source #
Post-processing of page concerns
Instances
Eq PageRender Source # | |
Defined in Web.Page.Types (==) :: PageRender -> PageRender -> Bool # (/=) :: PageRender -> PageRender -> Bool # | |
Show PageRender Source # | |
Defined in Web.Page.Types showsPrec :: Int -> PageRender -> ShowS # show :: PageRender -> String # showList :: [PageRender] -> ShowS # | |
Generic PageRender Source # | |
Defined in Web.Page.Types type Rep PageRender :: Type -> Type # from :: PageRender -> Rep PageRender x # to :: Rep PageRender x -> PageRender # | |
type Rep PageRender Source # | |
Defined in Web.Page.Types |
Css
Unifies css as either a Css
or as Text.
Instances
Show PageCss Source # | |
Generic PageCss Source # | |
Semigroup PageCss Source # | |
Monoid PageCss Source # | |
type Rep PageCss Source # | |
Defined in Web.Page.Types type Rep PageCss = D1 (MetaData "PageCss" "Web.Page.Types" "web-rep-0.4.0-1tSvqwxGHX6oFAw2f4hvL" False) (C1 (MetaCons "PageCss" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Css)) :+: C1 (MetaCons "PageCssText" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Text))) |
renderPageCss :: PageRender -> PageCss -> Text Source #
Render PageCss
as text.
JS
wrapper for JSAST
Unifies javascript as JSStatement
and script as Text
.
Instances
Eq PageJs Source # | |
Show PageJs Source # | |
Generic PageJs Source # | |
Semigroup PageJs Source # | |
Monoid PageJs Source # | |
type Rep PageJs Source # | |
Defined in Web.Page.Types type Rep PageJs = D1 (MetaData "PageJs" "Web.Page.Types" "web-rep-0.4.0-1tSvqwxGHX6oFAw2f4hvL" False) (C1 (MetaCons "PageJs" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 JS)) :+: C1 (MetaCons "PageJsText" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Text))) |
renderPageJs :: PageRender -> PageJs -> Text Source #
re-export modules
module Web.Page.SharedReps
module Web.Page.Render
module Web.Page.Server
module Web.Page.Bridge
module Web.Page.Html
module Web.Page.Html.Input
module Web.Page.Bootstrap
module Web.Page.Mathjax
module Data.Biapplicative
module Data.Bifunctor
re-exports
module Control.Monad.Trans.State
module Control.Applicative
A JSON value represented as a Haskell value.
Instances
Eq Value | |
Data Value | |
Defined in Data.Aeson.Types.Internal gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Value -> c Value # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Value # dataTypeOf :: Value -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Value) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Value) # gmapT :: (forall b. Data b => b -> b) -> Value -> Value # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Value -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Value -> r # gmapQ :: (forall d. Data d => d -> u) -> Value -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Value -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Value -> m Value # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Value -> m Value # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Value -> m Value # | |
Read Value | |
Show Value | |
IsString Value | |
Defined in Data.Aeson.Types.Internal fromString :: String -> Value # | |
Generic Value | |
Lift Value | |
Hashable Value | |
Defined in Data.Aeson.Types.Internal | |
ToJSON Value | |
Defined in Data.Aeson.Types.ToJSON | |
KeyValue Object | Constructs a singleton |
KeyValue Pair | |
FromJSON Value | |
NFData Value | |
Defined in Data.Aeson.Types.Internal | |
FromString Encoding | |
Defined in Data.Aeson.Types.ToJSON fromString :: String -> Encoding | |
FromString Value | |
Defined in Data.Aeson.Types.ToJSON fromString :: String -> Value | |
GToJSON Encoding arity (U1 :: Type -> Type) | |
GToJSON Value arity (V1 :: Type -> Type) | |
GToJSON Value arity (U1 :: Type -> Type) | |
ToJSON1 f => GToJSON Encoding One (Rec1 f) | |
ToJSON1 f => GToJSON Value One (Rec1 f) | |
ToJSON a => GToJSON Encoding arity (K1 i a :: Type -> Type) | |
(EncodeProduct arity a, EncodeProduct arity b) => GToJSON Encoding arity (a :*: b) | |
ToJSON a => GToJSON Value arity (K1 i a :: Type -> Type) | |
(WriteProduct arity a, WriteProduct arity b, ProductSize a, ProductSize b) => GToJSON Value arity (a :*: b) | |
(ToJSON1 f, GToJSON Encoding One g) => GToJSON Encoding One (f :.: g) | |
(ToJSON1 f, GToJSON Value One g) => GToJSON Value One (f :.: g) | |
FromPairs Value (DList Pair) | |
Defined in Data.Aeson.Types.ToJSON | |
v ~ Value => KeyValuePair v (DList Pair) | |
Defined in Data.Aeson.Types.ToJSON | |
(GToJSON Encoding arity a, ConsToJSON Encoding arity a, Constructor c) => SumToJSON' TwoElemArray Encoding arity (C1 c a) | |
Defined in Data.Aeson.Types.ToJSON | |
(GToJSON Value arity a, ConsToJSON Value arity a, Constructor c) => SumToJSON' TwoElemArray Value arity (C1 c a) | |
Defined in Data.Aeson.Types.ToJSON | |
type Rep Value | |
Defined in Data.Aeson.Types.Internal type Rep Value = D1 (MetaData "Value" "Data.Aeson.Types.Internal" "aeson-1.4.7.1-FbG0RnUAD5A6PLO1PMXqOS" False) ((C1 (MetaCons "Object" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 Object)) :+: (C1 (MetaCons "Array" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 Array)) :+: C1 (MetaCons "String" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 Text)))) :+: (C1 (MetaCons "Number" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 Scientific)) :+: (C1 (MetaCons "Bool" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 Bool)) :+: C1 (MetaCons "Null" PrefixI False) (U1 :: Type -> Type)))) |
:: IO a | computation to run first |
-> IO b | computation to run afterward (even if an exception was raised) |
-> IO a |
A specialised variant of bracket
with just a computation to run
afterward.
A map from keys to values. A map cannot contain duplicate keys; each key can map to at most one value.
Instances
KeyValue Object | Constructs a singleton |
Eq2 HashMap | |
Ord2 HashMap | |
Defined in Data.HashMap.Base | |
Show2 HashMap | |
Hashable2 HashMap | |
Defined in Data.HashMap.Base | |
FunctorWithIndex k (HashMap k) | |
Defined in Control.Lens.Indexed | |
FoldableWithIndex k (HashMap k) | |
TraversableWithIndex k (HashMap k) | |
Defined in Control.Lens.Indexed itraverse :: Applicative f => (k -> a -> f b) -> HashMap k a -> f (HashMap k b) # itraversed :: IndexedTraversal k (HashMap k a) (HashMap k b) a b # | |
Functor (HashMap k) | |
Foldable (HashMap k) | |
Defined in Data.HashMap.Base fold :: Monoid m => HashMap k m -> 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 # | |
Traversable (HashMap k) | |
ToJSONKey k => ToJSON1 (HashMap k) | |
Defined in Data.Aeson.Types.ToJSON liftToJSON :: (a -> Value) -> ([a] -> Value) -> HashMap k a -> Value # liftToJSONList :: (a -> Value) -> ([a] -> Value) -> [HashMap k a] -> Value # liftToEncoding :: (a -> Encoding) -> ([a] -> Encoding) -> HashMap k a -> Encoding # liftToEncodingList :: (a -> Encoding) -> ([a] -> Encoding) -> [HashMap k a] -> Encoding # | |
(FromJSONKey k, Eq k, Hashable k) => FromJSON1 (HashMap k) | |
Eq k => Eq1 (HashMap k) | |
Ord k => Ord1 (HashMap k) | |
Defined in Data.HashMap.Base | |
(Eq k, Hashable k, Read k) => Read1 (HashMap k) | |
Defined in Data.HashMap.Base | |
Show k => Show1 (HashMap k) | |
Hashable k => Hashable1 (HashMap k) | |
Defined in Data.HashMap.Base | |
(Eq k, Hashable k) => IsList (HashMap k v) | |
(Eq k, Eq v) => Eq (HashMap k v) | |
(Data k, Data v, Eq k, Hashable k) => Data (HashMap k v) | |
Defined in Data.HashMap.Base 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 :: (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) # | |
(Ord k, Ord v) => Ord (HashMap k v) | The order is total. Note: Because the hash is not guaranteed to be stable across library
versions, OSes, or architectures, neither is an actual order of elements in
|
Defined in Data.HashMap.Base | |
(Eq k, Hashable k, Read k, Read e) => Read (HashMap k e) | |
(Show k, Show v) => Show (HashMap k v) | |
(Eq k, Hashable k) => Semigroup (HashMap k v) | |
(Eq k, Hashable k) => Monoid (HashMap k v) | |
(Hashable k, Hashable v) => Hashable (HashMap k v) | |
Defined in Data.HashMap.Base | |
(ToJSON v, ToJSONKey k) => ToJSON (HashMap k v) | |
Defined in Data.Aeson.Types.ToJSON | |
(FromJSON v, FromJSONKey k, Eq k, Hashable k) => FromJSON (HashMap k v) | |
(NFData k, NFData v) => NFData (HashMap k v) | |
Defined in Data.HashMap.Base | |
(Eq k, Hashable k) => Ixed (HashMap k a) | |
Defined in Control.Lens.At | |
(Eq k, Hashable k) => At (HashMap k a) | |
(Hashable k, Eq k) => Wrapped (HashMap k a) | |
AsEmpty (HashMap k a) | |
Defined in Control.Lens.Empty | |
(t ~ HashMap k' a', Hashable k, Eq k) => Rewrapped (HashMap k a) t | Use |
Defined in Control.Lens.Wrapped | |
c ~ d => Each (HashMap c a) (HashMap d b) a b |
|
type Item (HashMap k v) | |
Defined in Data.HashMap.Base | |
type Index (HashMap k a) | |
Defined in Control.Lens.At | |
type IxValue (HashMap k a) | |
Defined in Control.Lens.At | |
type Unwrapped (HashMap k a) | |
Defined in Control.Lens.Wrapped |
fromList :: IsList l => [Item l] -> l #
The fromList
function constructs the structure l
from the given
list of Item l
void :: Functor f => f a -> f () #
discards or ignores the result of evaluation, such
as the return value of an void
valueIO
action.
Examples
Replace the contents of a
with unit:Maybe
Int
>>>
void Nothing
Nothing>>>
void (Just 3)
Just ()
Replace the contents of an
with unit,
resulting in an Either
Int
Int
:Either
Int
'()'
>>>
void (Left 8675309)
Left 8675309>>>
void (Right 8675309)
Right ()
Replace every element of a list with unit:
>>>
void [1,2,3]
[(),(),()]
Replace the second element of a pair with unit:
>>>
void (1,2)
(1,())
Discard the result of an IO
action:
>>>
mapM print [1,2]
1 2 [(),()]>>>
void $ mapM print [1,2]
1 2
sequenceA_ :: (Foldable t, Applicative f) => t (f a) -> f () #
Evaluate each action in the structure from left to right, and
ignore the results. For a version that doesn't ignore the results
see sequenceA
.
A space efficient, packed, unboxed Unicode text type.
Instances
Case analysis for the Bool
type.
evaluates to bool
x y px
when p
is False
, and evaluates to y
when p
is True
.
This is equivalent to if p then y else x
; that is, one can
think of it as an if-then-else construct with its arguments
reordered.
Examples
Basic usage:
>>>
bool "foo" "bar" True
"bar">>>
bool "foo" "bar" False
"foo"
Confirm that
and bool
x y pif p then y else x
are
equivalent:
>>>
let p = True; x = "bar"; y = "foo"
>>>
bool x y p == if p then y else x
True>>>
let p = False
>>>
bool x y p == if p then y else x
True
Since: base-4.7.0.0