Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sample Suave.IO does not compile in my F# project

Tags:

f#

suave

I'm trying to get this example from Suave.io compiling for a simple F# project: http://suave.io/

open Suave.Http.Applicatives
open Suave.Http.Successful
open Suave.Web
open Suave.Types
open Suave.Model

let greetings q =
  defaultArg (q ^^ "name") "World" |> sprintf "Hello %s"

let sample : WebPart = 
  path "/hello" >>= choose [
    GET  >>= request(fun r -> OK <| greetings (query r))
    POST >>= request(fun r -> OK <| greetings (form r))
    NOT_FOUND "Found no handlers" ]

Unfortunately I'm getting a compiler error on the (query r) part:

error FS0001: Expecting a type supporting the operator '^^' but given a function type. You may be missing an argument to a function.

I've tried to narrow down the compiler error to a few simple lines and now have this:

let greetings q =
  defaultArg (q ^^ "name") "World" |> sprintf "Hello %s"

let q (rqst : string) = query rqst
let t = greetings q

And now get that same compiler error on the greetings q line. The types in my example above are:

query:
  string -> (string -> Choice<'T,string>) -> HttpRequest -> Choice<'T,string>

greetings: 
 (string -> (string -> Choice<obj,string>) -> HttpRequest -> Choice<obj, string>) -> string

q:
  string -> ((string -> Choice<'a, string>) -> HttpRequest -> Choice<'a, string>)

So, my types aren't matching but I'm not too sure how I'd get these to match up.

Is the example just out of date? Any ideas how I can get this example to compile and run?

I'm running the RC build of Visual Studio 2015

Thanks

like image 623
Andy B Avatar asked Sep 29 '22 01:09

Andy B


1 Answers

I'm not familiar with Suave.IO, but looking at their source code, it indeed looks like an old sample code that no longer works. The definition of the query function is as follows:

let query queryKey f (req : HttpRequest) =
  req.queryParam queryKey
  |> Choice.from_option (sprintf "Missing query string key '%s'" queryKey)
  |> Choice.bind f

Note the three arguments - you're only passing the request, so the return value is not a value (or a collection), it's a function with two arguments.

On the other hand, the operator ^^ is used to retrieve a value from a collection by key.

Going through the history, it indeed seems that this is an obsolete and actually broken way of retrieving the collection of query parameters. The proper way now seems to be like this:

GET  >>= request(fun r -> OK <| greetings r.query)
POST >>= request(fun r -> OK <| greetings r.form)
like image 92
Luaan Avatar answered Oct 06 '22 02:10

Luaan