I'm trying to implement the isAdmin
function in a similar fashion to these Yesod book examples. The problem is that I want to keep my 'admin' emails in the database, but when I make a database query, isAdmin
loses its purity, so I have to return Handler-something IO Bool
instead of just Bool
. Now, this scraps the very nice syntax sugar in hamlet that allows to do so:
$if isAdmin
<p ...
Is there a way to still have a pure isAdmin
function even if I make a call to the database (I seriously doubt that... by the way, I don't want to pass any parameters to isAdmin
)? Or maybe I could still use the $if
syntax with the impure function?
P.S.: Currently, I am using a hack in the handler module:
isadmin <- isAdmin
So, I can write in the hamlet corresponding to that handler:
$if isadmin
But it is not universal and I like the first method more.
N.B.: I don't actually know Yesod; this answer is based on general Haskell practice.
Is there a way to still have a pure isAdmin function even if I make a call to the database (I seriously doubt that
It is not possible indeed. Access to an external database must, in one way or another, live in IO
; there is no way around it.
Currently, I am using a hack in the handler module:
isadmin <- isAdmin
So, I can write in the hamlet corresponding to that handler:
$if isadmin
That is not a hack; it is one of the standard ways of using the result from a monadic computation. In fact, in the Yesod book page you linked to, right before the isAdmin
example you mentioned, there is a snippet that runs a database query and uses the result with $if
in a very similar way to what you are doing now:
getBlogR :: Handler Html
getBlogR = do
-- etc.
entries <- runDB $ selectList [] [Desc EntryPosted]
-- etc.
$if null entries
-- etc.
P.S.:
N.B.: I don't want to pass any parameters to isAdmin
I wonder why you don't want to do so. Perhaps it is because your only need to check whether a single specific user is an admin. In that case, you should consider renaming your computation to isCurrentUserAdmin
(or whatever makes sense in your use case). Seeing a name like isAdmin
begs the question "who is an admin?", and so it is rather surprising that something with that name doesn't take any arguments.