Thomas
Thomas

Reputation: 12127

why can't I use do! when I want to ignore the result, in F#

In the following code:

let! _ = 
    connection
    |> Sql.existingConnection
    |> Sql.query $"LISTEN \"{accountId}.{notificationName}\""
    |> Sql.executeNonQueryAsync

I ignore the result and I thought I could replace this by a do! statement, but then:

do! 
    connection
    |> Sql.existingConnection
    |> Sql.query $"LISTEN \"{accountId}.{notificationName}\""
    |> Sql.executeNonQueryAsync

will not compile:

This expression was expected to have type 'int' but here has type 'unit'

and adding |> ignore at the end is not solving it. What would be the right way to do this?


edit:

here is the full code:

// start a loop, waiting for events
async {
    try
        // create a connection
        use connection = getConnection location

        // add the callback
        connection.Notification.Add (fun x -> callback (JObject.Parse x.Payload).["data"])

        // listen to the notifications
        let! _ =
            connection
            |> Sql.existingConnection
            |> Sql.query $"LISTEN \"{accountId}.{notificationName}\""
            |> Sql.executeNonQueryAsync

        // loop for events
        while true do
            try
                do! connection.WaitAsync()
            with ex ->
                error ex.Message
                Thread.Sleep(TimeSpan.FromSeconds(2.))
    with ex ->
        failwith $"{ex.Message}"
}
|> Async.StartAsTask
|> ignore

and the problem function (Sql.executeNonQueryAsync) is from this lib here: https://github.com/Zaid-Ajaj/Npgsql.FSharp/blob/50d3409fec844526e3c44901d64c8361b09e42a3/src/Npgsql.FSharp.fs (it's the last function of that file)

The lib is a F# wrapper around the Postgres' SQL client.

Upvotes: 0

Views: 167

Answers (1)

Ody
Ody

Reputation: 2047

You need to cast the Task<'T> to Task using the :> Operator.

do! 
    connection
    |> Sql.existingConnection
    |> Sql.query $"LISTEN \"{accountId}.{notificationName}\""
    |> Sql.executeNonQueryAsync
    :> Task

you can also make it consistent with Async.Ignore using the following extension

open System.Threading.Tasks
type Task with
    static member Ignore (t: Task<'T>) =
        t :> Task

so that it becomes

do! 
    connection
    |> Sql.existingConnection
    |> Sql.query $"LISTEN \"{accountId}.{notificationName}\""
    |> Sql.executeNonQueryAsync
    |> Task.Ignore

Upvotes: 1

Related Questions