Banana fritter

Posted on March 25, 2015

So I have more or less converted the todo app to Yaghnob (my coinage for the stack Yesod And GHcjs / Banana). The neat part is that we are now using the JSON instances provided by persistent on both server and client. (Someone on IRC pointed out that this doesn’t quite solve all your problems: if you change the schema you might end up with the two sides running different versions. But that’s a bridge I’ll cross when I come to it.)

Now, there’s a little niggle I’ve had all the way along, which I thought this change might help with… but so far it doesn’t. The internal model is now of type [Entity Todo]. The Todo part has just the Text of todo and a Bool indicating if it’s finished; the Entity adds the database id. Now consider a newly created entry. Till we have POSTed it to the server, we don’t know what the id should be.

Now, persistent handily gives us a type to represent the newly created entry: Todo. But we can’t use it. The banana network starts with a stream of low-level events (e.g. delete button clicked). Over this stream, it maps a function to produce a stream of functions each of type [Entity Todo] -> [Entity Todo]. That stream is then accumulated (into the initial list) to produce a behaviour that is the internal model.

Currently, we bodge round this by making the ajax call in the low-level event handler, so we get an Entity Todo to pass into the framework. But this seems wrong: no other ajax calls happen at this level. If we pass a Todo, though, what can we do with it? We could just about produce a stream with elements of type ([Entity Todo], Maybe Todo) representing the current list plus a possible new entry. But to bring the new entry into the list, we need IO, and that’s not available in accumB.

So I think we need an output that performs the ajax call, then makes a new input event with the result. Can newEvent do this? In fact, it seems to be possible simply to pass fire (the Handler value returned by newAddHandler) all the way down to the output functions, we can fire a new event, and it all works.

So, we’ll change the NewEnter event to simply carry a Text value. In justTodoFns, we don’t do anything with it. In update, we’ll perform the ajax call, and then fire a new event that carries the Entity Todo value. Yes! Fantastic!!

Next up is to shift things around so we have 3 cabal packages: yesod, ghcjs, and common, and teach shake how to build them all…