What kind of type is this?
Asked Answered
O

2

5

I just started working through Tamizhvendan S' book F# Applied and came across this code snippet:

type WebPart = Context -> Async<Context option>

I've been looking through Microsoft's F# docs as well as my favorite F# site, Scott Wlaschin's F# for Fun and Profit but have been unable to find any reference to this kind of type. It doesn't seem like a record type. It almost seems like a plain old function. So what is it?

Thanks for any help gals and guys.

Occidentalize answered 14/8, 2016 at 1:51 Comment(3)
This is a type abbreviation for a function.Ochre
So in this case, this WebPart takes a Context and simply wraps both an Option and an Async computation around it?Occidentalize
It could do anything - it isn't a function definition - just a convenience for writing type annotations.Ochre
C
12

The WebPart type you're looking at comes from Suave. You can read more about it at https://suave.io/async.html, but I'll summarize. You're correct: it is a type for a function. Specifically, it is a function that takes a Context (which in Suave is a combination of an HTTP request record and a response record), and returns a Context option asynchronously. That is, since some requests can fail, the function has the option of returning None instead of a value. And since some requests can take a long time, all requests are treated as returning asynchronously, hence the Async.

To chain two requests together, Suave provides the binding operator >=> so that you don't have to go through the boilerplate of typing async { match result1 with None -> None | Some x -> return! request2 x all the time; instead, you can just type request1 >=> request2 for the same effect.

If you need more help and reading through the Suave documentation hasn't provided the help you need, let us know and we'll try to explain further.

Cramfull answered 14/8, 2016 at 2:5 Comment(2)
Thanks for the help! What I've seen thus far of Suave has been pretty close to Scott Wlaschin's Railyway Oriented Programming article series.Occidentalize
Good insight! It is indeed the same concept as ROP, since there's a "success" path and a "failure" path, but there's an extra Async thrown in. But that's the great thing about functional programming: basic concepts carry over into lots of situations. The "bind" concept from ROP also applies to Async<Foo option> just as it applies to ROP-style Success / Failure types. Learn one concept, and you can apply it everywhere.Cramfull
M
3

This is too long to be a comment. And I have never used Suave. However, I think that I can guess from the monadic properties of the types involved that >=> is not a bind operator, but the Kleisli compositional operator. Without observing monad laws or trying to understand category theory, just by presuming the signatures to be:

val ( >>= ) :
  Async<'a option> -> ('a -> Async<'b option>) -> Async<'b option>
val ( >=> ) :
  ('a -> Async<'b option>) -> ('b -> Async<'c option>) -> 'a -> Async<'c option>

The bind operator takes an Async<'a option> and transforms it by way of a binder function 'a -> Async<'b option> into an Async<'b option>. The Kleisli operator composes two binder functions into a third.

These operators are working on monadic types and functions that are more generic than the concrete types described by a type abbreviation like type WebPart = Context -> Async<Context option>. An implementation of the operators follows almost naturally.

let (>>=) request1 binder = async { 
    let! result1 = request1
    match result1 with 
    | None -> return None 
    | Some x -> return! binder x }

let (>=>) f g a = f a >>= g
Mod answered 15/8, 2016 at 20:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.