So I have this working example (Snap + Postgres):
listBooks :: AppHandler ()
listBooks = do
results <- query_ "select * from books"
writeJSON $ (results :: [Book])
As an exercise I'm trying to rewrite this with >>=
operator, but the need to annotate type kills the aesthetics. I couldn't come up with anything better than:
query_ "select * from books" >>= return.(\x -> x :: [Book]) >>= writeJSON
Is there any other "smoother" way? (preferably without specifying the wrapping monad type)
You can shorten it slightly to
query_ "select * from books" >>= writeJSON . (\x -> x :: [Book])
Other than that, not yet, although there are plans to implement a GHC extension for a shortcut syntax
(:: [Book]) = (\x -> x :: [Book])
Looking at @duplode's link it seems like the code for it started getting written 3 days ago, so should be in the next GHC release.
If you turn on PartialTypeSignatures
, you can write:
query_ "select * from books" >>= (writeJSON :: [Book] -> _)
One could also spell this as a constraint on query_
; e.g. in your do
version, it would be:
listBooks :: AppHandler ()
listBooks = do
results <- query_ "select * from books" :: _ [Book]
writeJSON results
In future versions of GHC, there will also be visible type application. Assuming that writeJSON
or query_
has a suitable type declaration, you would then be able to write one of these:
query_ @[Book] "select * from books" >>= writeJSON
query_ "select * from books" >>= writeJSON @[Book]
Finally, if you are averse to type annotations but okay with term annotations, you could write
query_ "select * from books" >>= asAppliedTo [Book{}] writeJSON
where Book
is a hypothetical constructor for the Book
type (the point being that [Book{}]
, while a nonsense value, has a monomorphic type). I seem to recall that asAppliedTo
is a standard thing, but a quick hoogle doesn't reveal it; in any case, it is implemented similar to this:
asAppliedTo :: arg -> (arg -> result) -> (arg -> result)
asAppliedTo _ = id
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With