Search code examples
f#suave

F# Suave warbler function


I've started learning F# and Suave and I'm reading the book F# Applied.

One thing I'm struggling with is the warbler function. I know its something to do with deferring execution but I don't really understand why and when its needed.

Apparently we could also use the request function as an alternative to warbler.

Can anyone provide any more detail on why and when these functions are used.


Solution

  • These three functions are related in the sense that request and context are specialized versions of warbler. They all do the same thing - they inspect (some aspect of) their argument and give you back a function to apply to that argument.

    Remember that the basic "building block" of Suave, WebPart, is a function HttpContext -> Async<HttpContext option> rather than some concrete object. What this effectively means is that those three functions allow you to inspect this HttpContext and based on that compose a WebPart to use.

    At its core, what warbler does is very simple:

    let warbler f a = f a a  
    // ('t -> 't -> 'u) -> 't -> 'u
    

    You give it a function f and argument a. Function f looks at a and gives you back a new function 't -> 'u which is then applied to a.

    The thing about warbler is that it's entirely generic - you can use it anywhere you'd use context or request as long as the types align, but it doesn't know anything about the domain Suave is interested in.

    That's why there are the specialized versions of it that "speak the domain language":

    let request apply (a : HttpContext) = apply a.request a
    // (HttpRequest -> HttpContext -> 'a) -> HttpContext -> 'a 
    let context apply (a : HttpContext) = apply a a
    // (HttpContext -> HttpContext -> 'a) -> HttpContext -> 'a 
    

    Notice that they have the same "shape" as warbler - the only difference being that the HttpContext type is "hardcoded" - making it more convenient to use.