IMHO, the term "functional programming" doesn't do justice to the concept that lies behind it.   I like to think of it as Computational Oriented Programming.  

The idea is that you have computations (e.g.  state-full computation, non-deterministic, or reactive computation).  Each computation is a polymorphic type.   You think of your computations as having:

  • Constructors
  • Morphism
  • Observers

Constructors are either when you build a new computation from external types (e.g. putting an integer in a non-deterministic computation -list), or they are higher level combinators that combine two or more of your computation type to a new instance of your computation (concatenating two lists) .   Morphisms are when you apply a function to the values in your computation (add one to every element of the list).   End result is the same computation but the values have been morphed.   The key point in constructors is that the end result is the same computation type that you started with.   

If you always stay within your computation there is no value to the outside world.   So you need observers to export the result of your computation to other forms of computations.    Caveat:  the term observers here is not the same as the observers that is used in some of the FRP implementation.  

So when you think of say Functional Reactive Programming you start thinking in a about the constructors and combinators that you would need to express an event processing.    Your goal here is to define all the ways one can possibly construct an event handler.  A key point in your design must be to define the algebra of combining the FRP computation constructors.   The algebra would ensure that any complex combination of the constructors and morphism on the type would be coherent and consistent, otherwise you have a problem in your hand and you need to go back to the drawing board.    Once the constructors and combinators are defined a user would be able to define the event handlers.   Next you need to define the ways the user would be able to get the result of event handler computations to the outside world.   When you are done you have created a new type of computation that due to its polymorphic nature can be used in variety of contexts.   That in the essence how you do functional designs.