I haven't done any serious FRP, but thinking about your example of the drag adapter, wouldn't it be possible to do something like the following?
- Declare a stream consisting of the composite of two stream: a mouse down and a mouse up
- Map over the mouse down portion, transforming into an (x, y) coordinate
- Map over the mouse up portion, transforming into an (x, y) coordinate
- Produce a tuple of the two values
- Use the resulting signal that determines what to do with the drag
In Bacon.js, I think it would look something like this (haven't tested it):
var makeCoordinate = function(v) { return {x: v.clientX, y: v.clientY}; }
var mergeStreams = function(v1, v2) { return {down: makeCoordinate(v1), up: makeCoordinate(v2)}; };
var $html = $('html');
var mousedownStream = $html.asEventStream('mousedown');
var mouseupStream = $html.asEventStream('mouseup');
var dragStream = mousedownStream.flatMap(function() {
// Ensure that we only sample a single mousedown/mouseup pair.
return Bacon.zipWith([mousedownStream, mouseupStream], mergeStreams).
takeUntil(mouseupStream);
};
I don't mean to be pedantic - your point is well taken. This was definitely a mental exercise to write, and I have no experience debugging (though I imagine it would be difficult).
EDIT: For this particular example I actually made it more complicated than it needs to be. Example JS Fiddle here: http://jsfiddle.net/w6mCK/