5

I've been working a lot with F# lately, and recently wrote a little MVC application with a C# web project and an F# class library, the latter of which contained the bulk of the code.

I wanted to use the async controllers feature of the later versions of MVC where you can return a Task<ActionResult>. I was writing my code using F# asynchronous computation expressions but was getting very irritated having to constantly convert from Async<'T> to Task<'T> using Async.AwaitTask and StartAsTask.

Since I was learning computation expressions at the time, I thought "There must be a way to use computation expressions with Tasks as well as Async to allow better F#/C# interop", so I had a go:

type TaskBuilder () =
    member this.ReturnFrom task = task
    member this.Return value = Task.FromResult value
    member this.Bind (task : Task<'a>, continuation: 'a -> Task<'b>) =
        task.ContinueWith(fun (t : _ Task) ->
            (t.Result |> continuation).Result)
    member this.Zero () = Task.FromResult ()

This appears to work; running the following code:

let task = TaskBuilder()

task {
    let! data = (new WebClient()).DownloadStringTaskAsync(Uri "http://www.google.com")

    printfn "Downloaded from Google: %A" (data.Length)
}
|> ignore

task {
    let! data = (new WebClient()).DownloadStringTaskAsync(Uri "http://www.bing.com")

    printfn "Downloaded from Bing: %A" (data.Length)
}
|> ignore

printfn "Hello world"

yields the result:

Here
Downloaded from Bing: 39121
Downloaded from Google: 46005

It gives the appearance of asynchrony, and you end up with the correct type if you return from the computation expression, so I'm cautiously labelling this a success.

The thing that makes me suspicious is that I couldn't find any examples of other people trying this, so I'd appreciate some outside perspective on

  1. Has this worked?
  2. Is this a good idea in the first place?
Richiban
  • 5,569
  • 3
  • 30
  • 42
  • 3
    https://github.com/fsprojects/fsharpx/blob/master/src/FSharpx.Core/ComputationExpressions/Monad.fs#L994 – Mauricio Scheffer Jun 02 '14 at 15:28
  • 6
    This probably belongs on codereview.stackexchange.com. – N_A Jun 02 '14 at 18:09
  • You might find [this series](http://fsharpforfunandprofit.com/series/computation-expressions.html) helpful. – paul Jun 03 '14 at 20:43
  • 1
    I've already pointed to a working, fully-fledged computation expression around Task. I don't understand what's the need to point the OP to codereview. Just use that library. – Mauricio Scheffer Jun 06 '14 at 04:31

0 Answers0