Skip to content

Commit

Permalink
Add deferManyElse and deferEither to Heist.Compiled
Browse files Browse the repository at this point in the history
  • Loading branch information
kaol committed Jun 24, 2020
1 parent 7b7a09c commit f58893b
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 2 deletions.
1 change: 1 addition & 0 deletions CONTRIBUTORS
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ Carl Howells <[email protected]>
Edward Kmett
Will Langstroth <[email protected]>
Shane O'Brien <[email protected]>
Kari Pahula <[email protected]>
James Sanders <[email protected]>
Mark Wright <[email protected]>
2 changes: 2 additions & 0 deletions src/Heist/Compiled.hs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ module Heist.Compiled
, pureSplice

, deferMany
, deferManyElse
, defer
, deferEither
, deferMap
, mayDeferMap
, bindLater
Expand Down
37 changes: 35 additions & 2 deletions src/Heist/Compiled/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -749,12 +749,28 @@ deferMany :: (Foldable f, Monad n)
=> (RuntimeSplice n a -> Splice n)
-> RuntimeSplice n (f a)
-> Splice n
deferMany f getItems = do
deferMany = deferManyElse $ return mempty


------------------------------------------------------------------------------
-- | A version of 'deferMany' which has a default splice to run in the case
-- when there are no elements in the given list.
deferManyElse :: (Foldable f, Monad n)
=> Splice n
-> (RuntimeSplice n a -> Splice n)
-> RuntimeSplice n (f a)
-> Splice n
deferManyElse def f getItems = do
promise <- newEmptyPromise
chunks <- f $ getPromise promise
defaultChunk <- def
return $ yieldRuntime $ do
items <- getItems
foldMapM (\item -> putPromise promise item >> codeGen chunks) items
-- Use this instead of null for compatibility with pre 4.8 base
if foldr (\_ _ -> False) True items
then codeGen defaultChunk
else foldMapM (\item -> putPromise promise item >>
codeGen chunks) items


------------------------------------------------------------------------------
Expand All @@ -773,6 +789,23 @@ defer pf n = do
return $ action `mappend` res


------------------------------------------------------------------------------
-- | Much like 'either', takes a runtime computation and branches to the
-- respective splice depending on the runtime value.
deferEither :: Monad n
=> (RuntimeSplice n a -> Splice n)
-> (RuntimeSplice n b -> Splice n)
-> RuntimeSplice n (Either a b) -> Splice n
deferEither pfa pfb n = do
pa <- newEmptyPromise
pb <- newEmptyPromise
failureChunk <- pfa $ getPromise pa
successChunk <- pfb $ getPromise pb
return $ yieldRuntime $ n >>= either
(\x -> putPromise pa x >> codeGen failureChunk)
(\x -> putPromise pb x >> codeGen successChunk)


------------------------------------------------------------------------------
-- | A version of defer which applies a function on the runtime value.
deferMap :: Monad n
Expand Down

0 comments on commit f58893b

Please sign in to comment.