
I suspect I may not be understanding precisely what you mean. Perhaps you can describe this in more detail or with an example?
The easiest way to see the difference is by looking at some of the combinators. Notice that things like 'hold', 'scan'/'accum', and 'tag' are real functions. In a first-class FRP system these would have types like the following: hold :: a -> Event a -> Moment (Behaviour a) scan :: a -> Event (a -> a) -> Moment (Event a) tag :: Behaviour (a -> b) -> Event a -> Event b The Moment monad is not inherent to the way the underlying state machine is constructed, but acts merely as a provider for the notion of "now". Since 'tag' doesn't need that notion, it's a completely pure function. You can have that function in AFRP as well: fmap :: (a -> b) -> Event a -> Event b However, unlike 'fmap', 'tag' makes sense in a pure context. You can pass an Event and a Behaviour to a different thread via an MVar, combine them there, then send the result back, and it will still work in the context of the greater application (no isolated state machines). You can hold an event in any concurrent thread, etc. Another example is that if the underlying monad is nontrivial (say IO) you can't easily split behaviours in a pure context in AFRP. This restriction does not exist in first-class FRP: unzipB :: Behavior (a, b) -> (Behavior a, Behavior b) splitE :: Event (Either a b) -> (Event a, Event b) In AFRP you always have to do it in the context of the underlying state machine, i.e. MSF/SF/Wire, which means that AFRP forces you to manage all data structures holding reactive values as part of it or, again, have isolated state machines. With first-class FRP there is nothing wrong with keeping a data structure of behaviours in an MVar and have two concurrent threads modify it: MVar (Map K (Behaviour String)) AFRP requires the following instead, and unless all changes are planned within the state machine and communicated via 'A' changes actually build up in terms of complexity (you can't just keep composing it with more and more MSF actions for free): MVar (MSF IO A (Map K String)) Let me make clear that you can express all of these things in AFRP. In fact it's easily more powerful than first-class FRP, because if the system exposes it, you get full access to the expressivity of what is basically a generic state machine. Just to provide one example: there is no first-class counterpart to 'manage' from wires, because that combinator only really makes sense in the context of the underlying state machine. But all of this comes at the expense of giving up first-class behaviours and events in the above sense. If this still doesn't convince you, I strongly suggest that you give reflex a try. It has a very similar controller interface to AFRP (stepWire/unMSF) in that it gives you control over the main loop, so it shouldn't feel too alien. As a final remark due to all these issues and more with AFRP most of my research in the past few years went into getting rid of the A while retaining most of its advantages. Reflex (by Ryan Trinkle, not me) is almost there: it has the performance, the predictability and the expressivity. The only missing component is an equivalent to 'manage', i.e. effects without the controller round-trip, or what I call "switching with effects". Greets ertes