The type X is not compatible with type Y

Recently our firm switched from BitBucket to Azure DevOps. This allowed us to create our own extensions using Azure Services REST API. Microsoft already delivers .NET client, so getting what you want is pretty straightforward.

For example, retrieving Pull Request data with C# looks like this

var conn = new VssConnection(
    new Uri("https://dev.azure.com/<org>"),
    new VssBasicCredential(
        string.Empty, // You can give anything while providing PAT
        "<pat>"));

var client = await conn.GetClientAsync<GitHttpClient>();
var pr = await client.GetPullRequestAsync(
    project: "...",
    repositoryId: "...",
    pullRequestId: 42
);

Out of curiosity, I've tried doing the same with F#, but I quickly hit the wall

let pat = "<pat>"
let url = new Uri("https://dev.azure.com/<org>")
let cred = new VssBasicCredential(String.Empty, pat)
let conn = new VssConnection(url, cred) // Err!

The code above, although very similar to previous one, was not compiling. The compiler was telling me that

The type 'VssBasicCredential' is not compatible with type 'VssCredentials' 

Ok, fair enough, F# doesn't allow for implicit casting (which is actually reasonable to me).

So I tried with downcast

let cred = new VssBasicCredential(String.Empty, pat) :> VssCredentials

But it didn't work neither (and I still cannot tell why).

After some more googling I found page with some common issue F# compiler troubleshooting. The first issue was referring to what exactly I was after.

I quickly figured out the new-to-me syntax and got things working.

let cred = VssCredentials (new VssBasicCredential(String.Empty, pat))

And here is the whole working solution

open FSharp.Control.Tasks.V2 // https://github.com/rspeele/TaskBuilder.fs

let pat = "<pat>"
let url = new Uri("https://dev.azure.com/<org>")
let cred = VssCredentials (new VssBasicCredential(String.Empty, pat))
let conn = new VssConnection(url, cred)
let statuses = task {
    let! client = conn.GetClientAsync<GitHttpClient>()
    let! statuses = client.GetPullRequestAsync("<project>", "<repoId>", 42)
    return statuses
}
comments powered by Disqus