Skip to content

Commit d5edfa3

Browse files
committed
Add deferManyElse and deferEither to Heist.Compiled
1 parent 7b7a09c commit d5edfa3

File tree

3 files changed

+42
-2
lines changed

3 files changed

+42
-2
lines changed

CONTRIBUTORS

+1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ Carl Howells <[email protected]>
44
Edward Kmett
55
Will Langstroth <[email protected]>
66
Shane O'Brien <[email protected]>
7+
Kari Pahula <[email protected]>
78
James Sanders <[email protected]>
89
Mark Wright <[email protected]>

src/Heist/Compiled.hs

+2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ module Heist.Compiled
2828
, pureSplice
2929

3030
, deferMany
31+
, deferManyElse
3132
, defer
33+
, deferEither
3234
, deferMap
3335
, mayDeferMap
3436
, bindLater

src/Heist/Compiled/Internal.hs

+39-2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import qualified Text.XmlHtml.HTML.Meta as X
3737
------------------------------------------------------------------------------
3838
#if !MIN_VERSION_base(4,8,0)
3939
import Data.Foldable (Foldable)
40+
import Data.Monoid
4041
#endif
4142
import qualified Data.Foldable as Foldable
4243
------------------------------------------------------------------------------
@@ -749,12 +750,31 @@ deferMany :: (Foldable f, Monad n)
749750
=> (RuntimeSplice n a -> Splice n)
750751
-> RuntimeSplice n (f a)
751752
-> Splice n
752-
deferMany f getItems = do
753+
deferMany = deferManyElse $ return mempty
754+
755+
756+
------------------------------------------------------------------------------
757+
-- | A version of 'deferMany' which has a default splice to run in the case
758+
-- when there are no elements in the given list.
759+
deferManyElse :: (Foldable f, Monad n)
760+
=> Splice n
761+
-> (RuntimeSplice n a -> Splice n)
762+
-> RuntimeSplice n (f a)
763+
-> Splice n
764+
deferManyElse def f getItems = do
753765
promise <- newEmptyPromise
754766
chunks <- f $ getPromise promise
767+
defaultChunk <- def
755768
return $ yieldRuntime $ do
756769
items <- getItems
757-
foldMapM (\item -> putPromise promise item >> codeGen chunks) items
770+
if nullGeneric items
771+
then codeGen defaultChunk
772+
else foldMapM (\item -> putPromise promise item >>
773+
codeGen chunks) items
774+
where
775+
-- Use this instead of null for compatibility with pre 4.8 base
776+
nullGeneric = foldrGeneric (\_ _ -> False) True
777+
foldrGeneric f' z t = appEndo (foldMap (Endo . f') t) z
758778

759779

760780
------------------------------------------------------------------------------
@@ -773,6 +793,23 @@ defer pf n = do
773793
return $ action `mappend` res
774794

775795

796+
------------------------------------------------------------------------------
797+
-- | Much like 'either', takes a runtime computation and branches to the
798+
-- respective splice depending on the runtime value.
799+
deferEither :: Monad n
800+
=> (RuntimeSplice n a -> Splice n)
801+
-> (RuntimeSplice n b -> Splice n)
802+
-> RuntimeSplice n (Either a b) -> Splice n
803+
deferEither pfa pfb n = do
804+
pa <- newEmptyPromise
805+
pb <- newEmptyPromise
806+
failureChunk <- pfa $ getPromise pa
807+
successChunk <- pfb $ getPromise pb
808+
return $ yieldRuntime $ n >>= either
809+
(\x -> putPromise pa x >> codeGen failureChunk)
810+
(\x -> putPromise pb x >> codeGen successChunk)
811+
812+
776813
------------------------------------------------------------------------------
777814
-- | A version of defer which applies a function on the runtime value.
778815
deferMap :: Monad n

0 commit comments

Comments
 (0)