LoCo Day 5

Yet another day with little-to-no direct progress, but I think I did finally get to the heart of the problem I’ve been wrestling with. I’ve asked on Stack Overflow if there’s a way around it, in case I’m still missing something, but I don’t think I am.

The basic problem I ran into is this: In Heist, page templates can only run Haskell code by invoking splices, which are defined in the context of the program’s application stack. As a result, splices can’t see anything that doesn’t directly originate in that monad. However, when using web-routes for type-safe URLs, parameters passed via the URL path itself, instead of the query string, are inaccessible from the application monad; instead, they are accessed by pattern-matching against the type-safe URL. Likewise, the session object created before invoking the web-routes part of the code lives outside of the application monad. As a result, splices can’t get at URL path parameters or the session object, and there doesn’t seem to be a way around this inherent design limitation.

The problem doesn’t seem to arise when using Snap instead of Happstack, since Snap’s routing mechanism extracts URL path parameters, gives them names, and treats them as though they were other query string parameters, in which case they can be accessed via a Snap-based monad. I imagine something similar happens when working with sessions. Since Heist arose out of the Snap project, it’s not surprising its splices are limited to getting things out of the application monad, since in Snap that’s less of a limitation than it is in Happstack. No wonder that all the examples of Heist I’ve come across hand-wave getting request parameters by assuming there’s something in the application monad to do that.

I think that means I should give up on Heist (barring an answer to the aforementioned question that points out a way around this issue entirely) and use Blaze to generate HTML instead, at least for now. Although I’m stuck with Blaze’s quasi-monadic syntax instead of something that looks like actual HTML, at least I get some extra type-safety guarantees by having the HTML templates be Haskell code instead of standalone files loaded at runtime.

I did effectively lose a couple days wrestling with this, but at least I’m coming out of it with a better understanding of what these libraries can and can’t do.