Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# - Writing a function that accepts both non-generic and generic argument

Tags:

f#

I defined await function like this:

let await (task : Task<'a>) =
    task |> Async.AwaitTask |> Async.RunSynchronously

and two tasks like this:

let stringTask = new Task<string>(fun () -> "something")

let unitTask = new Task(fun () -> printf "something")

Calling them like this:

let stringResult = await stringTask
await unitTask

But the second is not generic and I can't call await for it, thus I edited the function argument like this:

let await (task : Task) =
    task |> Async.AwaitTask |> Async.RunSynchronously

The problem is now the await stringTask is returning unit instead of string.

How should I write the await function to accept both Task<'a> and Task as the parameter and await it?

like image 913
Avestura Avatar asked Nov 16 '25 16:11

Avestura


1 Answers

Your original definition for await is fine.

The problem is with unitTask which is not generic. Make it generic the same way you did with stringTask:

let unitTask = new Task<unit>(fun () -> printf "something")

If you want to handle both generic Task<'a> and non-generic Task, you have 2 options.

Create 2 await functions (the functional way):

let await     (task : Task<'a>) = task |> Async.AwaitTask |> Async.RunSynchronously
let awaitUnit (task : Task    ) = task |> Async.AwaitTask |> Async.RunSynchronously

or create 2 Await members for instance on type Task (the OO way):

type Task with 
    static member Await (task : Task    ) = task |> Async.AwaitTask |> Async.RunSynchronously
    static member Await (task : Task<'a>) = task |> Async.AwaitTask |> Async.RunSynchronously

By convention members use Pascal case so I used Await instead of await.

Remember to call task.Start() before you call your await.

like image 139
AMieres Avatar answered Nov 19 '25 10:11

AMieres



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!