rspeele / TaskBuilder.fs

F# computation expression builder for System.Threading.Tasks

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Non-generic Tasks

kentcb opened this issue · comments

Hello,

Thanks for this useful library.

What is the guidance for working with non-generic Tasks? A simple repro of my issue:

let doesThisWork : System.Threading.Tasks.Task =
    task {
        do! System.Threading.Tasks.Task.Delay(1000)
    }

Which produces this error:

FS0001    This expression was expected to have type
    'Threading.Tasks.Task'    
but here has type
    'Threading.Tasks.Task<unit>'

One workaround we have is:

type System.Threading.Tasks.Task with

    static member Ignore (task: Task<'T>) : Task =
        task :> Task

And then:

let doesThisWork : System.Threading.Tasks.Task =
    task {
        do! System.Threading.Tasks.Task.Delay(1000)
    } |> Task.Ignore

But this feels rather hacky.

It doesn't feel hacky to me.
It feels explicit.

Yes it feels pretty reasonable to me

@kentcb This is pretty standard with generics when going from F# unit (as 'T) to void in C# where you have this "equivalent" type for the void case in C# but just a single type in F#.

Actually, F#+ has exactly that same Task.Ignore function, for the same purpose.

Another option is the upcast operator. I find this nice when implementing interfaces that want a non-generic Task.

let doesThisWork : System.Threading.Tasks.Task =
    upcast task {
        do! System.Threading.Tasks.Task.Delay(1000)
    }

Thanks all! Glad we're on the right track.