module Hakyllbars.Compiler where

import Control.Applicative (liftA3)
import Control.Monad.State.Strict
import Data.Bifunctor
import Data.List.NonEmpty as NonEmpty
import Hakyll.Core.Compiler.Internal
import Hakyllbars.Ast
import Hakyllbars.Common
import Hakyllbars.Context hiding (field)
import Hakyllbars.Source.Parser (parse)

-- | Takes an item and compiles a template from it.
compileTemplateItem :: Item String -> Compiler Template
compileTemplateItem :: Item String -> Compiler Template
compileTemplateItem Item String
item = do
  let filePath :: String
filePath = Identifier -> String
toFilePath forall a b. (a -> b) -> a -> b
$ forall a. Item a -> Identifier
itemIdentifier Item String
item
  forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show) forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ String -> String -> Either ParseError Template
parse String
filePath (forall a. Item a -> a
itemBody Item String
item)

loadTemplate :: Identifier -> TemplateRunner a Template
loadTemplate :: forall a. Identifier -> TemplateRunner a Template
loadTemplate = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Item a -> a
itemBody forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (Binary a, Typeable a) => Identifier -> Compiler (Item a)
load

applyTemplate :: Identifier -> TemplateRunner String ()
applyTemplate :: Identifier -> TemplateRunner String ()
applyTemplate =
  forall a. Identifier -> TemplateRunner a Template
loadTemplate
    forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Template -> TemplateRunner String String
reduceTemplate
    forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Compiler (Item a)
makeItem
    forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> forall a. Item a -> TemplateRunner a ()
tplPushItem

applyAsTemplate :: TemplateRunner String ()
applyAsTemplate :: TemplateRunner String ()
applyAsTemplate =
  forall a.
(Item a -> TemplateRunner a (Item a)) -> TemplateRunner a ()
tplModifyItem do
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. Item String -> Compiler Template
compileTemplateItem
      forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Template -> TemplateRunner String String
reduceTemplate
      forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Compiler (Item a)
makeItem

reduceTemplate :: Template -> TemplateRunner String String
reduceTemplate :: Template -> TemplateRunner String String
reduceTemplate (Template [Block]
bs String
src) =
  forall a b. String -> TemplateRunner a b -> TemplateRunner a b
tplWithCall (String
"template " forall a. [a] -> [a] -> [a]
++ String
src) ([Block] -> TemplateRunner String String
reduceBlocks [Block]
bs)

reduceBlocks :: [Block] -> TemplateRunner String String
reduceBlocks :: [Block] -> TemplateRunner String String
reduceBlocks = ContextValue String -> TemplateRunner String String
stringify forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall v a. IntoValue v a => v -> ContextValue a
intoValue forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< [Block] -> TemplateRunner String [ContextValue String]
applyBlocks

applyBlocks :: [Block] -> TemplateRunner String [ContextValue String]
applyBlocks :: [Block] -> TemplateRunner String [ContextValue String]
applyBlocks = forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Block -> TemplateRunner String (ContextValue String)
applyBlock

applyBlock :: Block -> TemplateRunner String (ContextValue String)
applyBlock :: Block -> TemplateRunner String (ContextValue String)
applyBlock = forall x a b.
(x -> SourcePos)
-> (x -> TemplateRunner a b) -> x -> TemplateRunner a b
tplWithPos Block -> SourcePos
getBlockPos \case
  TextBlock String
t SourcePos
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall v a. IntoValue v a => v -> ContextValue a
intoValue String
t
  ExpressionBlock Expression
e SourcePos
_ -> forall a. Expression -> TemplateRunner a (ContextValue a)
eval Expression
e
  CommentBlock {} -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. ContextValue a
EmptyValue
  ChromeBlock Expression
e [Block]
bs SourcePos
pos ->
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall v a. IntoValue v a => v -> ContextValue a
intoValue do
      String
bs' <- [Block] -> TemplateRunner String String
reduceBlocks [Block]
bs
      forall a. Expression -> TemplateRunner a (ContextValue a)
eval Expression
e forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        FunctionValue ContextValue String -> TemplateRunner String (ContextValue String)
f -> ContextValue String -> TemplateRunner String (ContextValue String)
f (forall v a. IntoValue v a => v -> ContextValue a
intoValue String
bs')
        ContextValue String
x -> forall a b. String -> TemplateRunner a b
tplFail forall a b. (a -> b) -> a -> b
$ String
"invalid chrome function " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ContextValue String
x forall a. [a] -> [a] -> [a]
++ String
" near " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show SourcePos
pos
  AltBlock (ApplyBlock Expression
e [Block]
bs SourcePos
_ :| [ApplyBlock]
alts) Maybe DefaultBlock
maybeDefault SourcePos
_ ->
    forall v a. IntoValue v a => v -> ContextValue a
intoValue forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Expression
-> [Block]
-> [ApplyBlock]
-> Maybe DefaultBlock
-> TemplateRunner String [ContextValue String]
applyAltBlock Expression
e [Block]
bs [ApplyBlock]
alts Maybe DefaultBlock
maybeDefault

applyAltBlock ::
  Expression ->
  [Block] ->
  [ApplyBlock] ->
  Maybe DefaultBlock ->
  TemplateRunner String [ContextValue String]
applyAltBlock :: Expression
-> [Block]
-> [ApplyBlock]
-> Maybe DefaultBlock
-> TemplateRunner String [ContextValue String]
applyAltBlock Expression
guard' [Block]
bs [ApplyBlock]
alts Maybe DefaultBlock
maybeDefault =
  forall a. Expression -> TemplateRunner a (ContextValue a)
eval Expression
guard' forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    FunctionValue ContextValue String -> TemplateRunner String (ContextValue String)
f -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ContextValue String -> TemplateRunner String (ContextValue String)
f (forall v a. IntoValue v a => v -> ContextValue a
intoValue [Block]
bs)
    ContextValue String
x ->
      forall a. ContextValue a -> TemplateRunner a Bool
isTruthy ContextValue String
x forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Bool
True -> [Block] -> TemplateRunner String [ContextValue String]
applyBlocks [Block]
bs
        Bool
False -> case [ApplyBlock]
alts of
          ApplyBlock Expression
guard'' [Block]
bs' SourcePos
_ : [ApplyBlock]
alts' -> Expression
-> [Block]
-> [ApplyBlock]
-> Maybe DefaultBlock
-> TemplateRunner String [ContextValue String]
applyAltBlock Expression
guard'' [Block]
bs' [ApplyBlock]
alts' Maybe DefaultBlock
maybeDefault
          [] -> case Maybe DefaultBlock
maybeDefault of
            Just (DefaultBlock [Block]
bs' SourcePos
_) -> [Block] -> TemplateRunner String [ContextValue String]
applyBlocks [Block]
bs'
            Maybe DefaultBlock
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return []

eval :: Expression -> TemplateRunner a (ContextValue a)
eval :: forall a. Expression -> TemplateRunner a (ContextValue a)
eval = forall x a b.
(x -> SourcePos)
-> (x -> TemplateRunner a b) -> x -> TemplateRunner a b
tplWithPos Expression -> SourcePos
getExpressionPos \case
  NameExpression String
name SourcePos
pos -> do
    (Context a
context, Item a
item, [String]
trace) <-
      forall (f :: * -> *) a b c d.
Applicative f =>
(a -> b -> c -> d) -> f a -> f b -> f c -> f d
liftA3 (,,) forall a. TemplateRunner a (Context a)
tplContext forall a. TemplateRunner a (Item a)
tplItem forall a. TemplateRunner a [String]
tplTrace forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
`catchError` \[String]
e -> do
        forall a b. String -> TemplateRunner a b
tplFail forall a b. (a -> b) -> a -> b
$ String
"Caught error in template: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show [String]
e forall a. [a] -> [a] -> [a]
++ String
" near " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show SourcePos
pos
    TemplateState a
s <- forall s (m :: * -> *). MonadState s m => m s
get
    (ContextValue a
x, TemplateState a
s') <-
      forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$
        forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT (forall a. Context a -> ContextFunction a
unContext Context a
context String
name) TemplateState a
s forall a.
Compiler a -> (CompilerErrors String -> Compiler a) -> Compiler a
`compilerCatch` \case
          CompilationFailure NonEmpty String
ne ->
            forall a. [String] -> Compiler a
compilerThrow (forall a. NonEmpty a -> [a]
NonEmpty.toList NonEmpty String
ne)
          CompilationNoResult [String]
ss ->
            -- TODO figure out how to get state changes to persist if value comes back empty
            forall (m :: * -> *) a. Monad m => a -> m a
return (forall a.
String -> Item a -> [String] -> [String] -> ContextValue a
UndefinedValue String
name Item a
item (forall a. Show a => a -> String
show SourcePos
pos forall a. a -> [a] -> [a]
: [String]
trace) [String]
ss, TemplateState a
s)
    forall s (m :: * -> *). MonadState s m => s -> m ()
put TemplateState a
s'
    forall (m :: * -> *) a. Monad m => a -> m a
return ContextValue a
x
  StringExpression String
s SourcePos
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall v a. IntoValue v a => v -> ContextValue a
intoValue String
s
  IntExpression Int
n SourcePos
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall v a. IntoValue v a => v -> ContextValue a
intoValue Int
n
  DoubleExpression Double
x SourcePos
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall v a. IntoValue v a => v -> ContextValue a
intoValue Double
x
  BoolExpression Bool
b SourcePos
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall v a. IntoValue v a => v -> ContextValue a
intoValue Bool
b
  ApplyExpression Expression
f Expression
x SourcePos
_ -> forall {a}.
Expression
-> Expression -> StateT (TemplateState a) Compiler (ContextValue a)
apply Expression
f Expression
x
  AccessExpression Expression
target Expression
field SourcePos
pos ->
    forall a. Expression -> TemplateRunner a (ContextValue a)
eval Expression
target forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      ContextValue Context a
target' -> do
        String
name <-
          forall a. Expression -> TemplateRunner a (ContextValue a)
eval Expression
field forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
            StringValue String
x -> forall (m :: * -> *) a. Monad m => a -> m a
return String
x
            ContextValue a
x -> forall a b. String -> TemplateRunner a b
tplFail forall a b. (a -> b) -> a -> b
$ String
"invalid field " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ContextValue a
x forall a. [a] -> [a] -> [a]
++ String
" near " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (Expression -> SourcePos
getExpressionPos Expression
field)
        TemplateState a
s <- forall s (m :: * -> *). MonadState s m => m s
get
        (ContextValue a
x, TemplateState a
s') <-
          forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$
            forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT (forall a. Context a -> ContextFunction a
unContext Context a
target' String
name) TemplateState a
s forall a.
Compiler a -> (CompilerErrors String -> Compiler a) -> Compiler a
`compilerCatch` \case
              CompilationFailure NonEmpty String
errors ->
                forall a. [String] -> Compiler a
compilerThrow (forall a. NonEmpty a -> [a]
NonEmpty.toList NonEmpty String
errors)
              CompilationNoResult [String]
_ ->
                -- TODO figure out how to get state changes to persist if value comes back empty
                forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. ContextValue a
EmptyValue, TemplateState a
s)
        forall s (m :: * -> *). MonadState s m => s -> m ()
put TemplateState a
s'
        forall (m :: * -> *) a. Monad m => a -> m a
return ContextValue a
x
      ContextValue a
EmptyValue -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. ContextValue a
EmptyValue
      UndefinedValue {} -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. ContextValue a
EmptyValue
      ContextValue a
x -> forall a b. String -> TemplateRunner a b
tplFail forall a b. (a -> b) -> a -> b
$ String
"invalid context " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ContextValue a
x forall a. [a] -> [a] -> [a]
++ String
" near " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show SourcePos
pos
  FilterExpression Expression
x Expression
f SourcePos
_ -> forall {a}.
Expression
-> Expression -> StateT (TemplateState a) Compiler (ContextValue a)
apply Expression
f Expression
x
  ContextExpression [(String, Expression)]
pairs SourcePos
_ -> do
    [(String, ContextValue a)]
pairs' <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second forall a. Expression -> TemplateRunner a (ContextValue a)
eval) [(String, Expression)]
pairs
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. Context a -> ContextValue a
ContextValue (forall v a. IntoContext v a => v -> Context a
intoContext [(String, ContextValue a)]
pairs')
  ListExpression [Expression]
xs SourcePos
_ -> forall v a. IntoValue v a => v -> ContextValue a
intoValue forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall a. Expression -> TemplateRunner a (ContextValue a)
eval [Expression]
xs
  where
    apply :: Expression
-> Expression -> StateT (TemplateState a) Compiler (ContextValue a)
apply Expression
f Expression
x =
      forall a. Expression -> TemplateRunner a (ContextValue a)
eval Expression
f forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        FunctionValue ContextValue a
-> StateT (TemplateState a) Compiler (ContextValue a)
f' -> ContextValue a
-> StateT (TemplateState a) Compiler (ContextValue a)
f' (forall a. TemplateRunner a (ContextValue a) -> ContextValue a
ThunkValue forall a b. (a -> b) -> a -> b
$ forall a. Expression -> TemplateRunner a (ContextValue a)
eval Expression
x)
        ContextValue a
x' -> forall a b. String -> TemplateRunner a b
tplFail forall a b. (a -> b) -> a -> b
$ String
"invalid function " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ContextValue a
x' forall a. [a] -> [a] -> [a]
++ String
" in " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (Expression -> SourcePos
getExpressionPos Expression
f)

stringify :: ContextValue String -> TemplateRunner String String
stringify :: ContextValue String -> TemplateRunner String String
stringify = \case
  ContextValue String
EmptyValue -> forall (m :: * -> *) a. Monad m => a -> m a
return String
""
  UndefinedValue String
name Item String
item [String]
trace [String]
errors ->
    forall a b. String -> TemplateRunner a b
tplFail forall a b. (a -> b) -> a -> b
$
      String
"can't stringify undefined value "
        forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show String
name
        forall a. [a] -> [a] -> [a]
++ String
"\nin item context for "
        forall a. [a] -> [a] -> [a]
++ forall a. Item a -> String
itemFilePath Item String
item
        forall a. [a] -> [a] -> [a]
++ String
"\ntrace=[\n\t"
        forall a. [a] -> [a] -> [a]
++ forall a. [a] -> [[a]] -> [a]
intercalate String
",\n\t" [String]
trace
        forall a. [a] -> [a] -> [a]
++ String
"\n],\nsuppressed=[\n\t"
        forall a. [a] -> [a] -> [a]
++ forall a. [a] -> [[a]] -> [a]
intercalate String
",\n\t" [String]
errors
        forall a. [a] -> [a] -> [a]
++ String
"\n]\n"
  ContextValue {} -> forall a b. String -> TemplateRunner a b
tplFail String
"can't stringify context"
  ListValue [ContextValue String]
xs -> forall a. Monoid a => [a] -> a
mconcat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM ContextValue String -> TemplateRunner String String
stringify [ContextValue String]
xs
  BoolValue Bool
b -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show Bool
b
  StringValue String
s -> forall (m :: * -> *) a. Monad m => a -> m a
return String
s
  DoubleValue Double
x -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show Double
x
  IntValue Int
n -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show Int
n
  FunctionValue {} -> forall a b. String -> TemplateRunner a b
tplFail String
"can't stringify function"
  BlockValue Block
block -> case Block
block of
    TextBlock String
t SourcePos
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return String
t
    CommentBlock {} -> forall (m :: * -> *) a. Monad m => a -> m a
return String
""
    ExpressionBlock Expression
e SourcePos
_ -> ContextValue String -> TemplateRunner String String
stringify forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. Expression -> TemplateRunner a (ContextValue a)
eval Expression
e
    Block
_ -> ContextValue String -> TemplateRunner String String
stringify forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Block -> TemplateRunner String (ContextValue String)
applyBlock Block
block
  ItemValue Item String
item -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. Item a -> a
itemBody Item String
item
  ThunkValue TemplateRunner String (ContextValue String)
fx -> ContextValue String -> TemplateRunner String String
stringify forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. ContextValue a -> TemplateRunner a (ContextValue a)
force forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< TemplateRunner String (ContextValue String)
fx
  PairValue (ContextValue String
_, ContextValue String
x) -> ContextValue String -> TemplateRunner String String
stringify ContextValue String
x

isTruthy :: ContextValue a -> TemplateRunner a Bool
isTruthy :: forall a. ContextValue a -> TemplateRunner a Bool
isTruthy = \case
  ContextValue a
EmptyValue -> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
  UndefinedValue {} -> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
  ContextValue {} -> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
  ListValue [ContextValue a]
xs -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ContextValue a]
xs)
  BoolValue Bool
x -> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
x
  StringValue String
x -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
x)
  DoubleValue Double
x -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Double
x forall a. Eq a => a -> a -> Bool
/= Double
0
  IntValue Int
x -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Int
x forall a. Eq a => a -> a -> Bool
/= Int
0
  FunctionValue {} -> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
  BlockValue {} -> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
  ItemValue Item a
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
  ThunkValue TemplateRunner a (ContextValue a)
fx -> forall a. ContextValue a -> TemplateRunner a Bool
isTruthy forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. ContextValue a -> TemplateRunner a (ContextValue a)
force forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< TemplateRunner a (ContextValue a)
fx
  PairValue (ContextValue a
_, ContextValue a
x) -> forall a. ContextValue a -> TemplateRunner a Bool
isTruthy ContextValue a
x

force :: ContextValue a -> TemplateRunner a (ContextValue a)
force :: forall a. ContextValue a -> TemplateRunner a (ContextValue a)
force = \case
  ThunkValue TemplateRunner a (ContextValue a)
fx -> forall a. ContextValue a -> TemplateRunner a (ContextValue a)
force forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< TemplateRunner a (ContextValue a)
fx
  ContextValue a
x -> forall (m :: * -> *) a. Monad m => a -> m a
return ContextValue a
x