Skip to content

chkimes/arbitrary-async-return-nullable

master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 

Nullable Tasklike

Quick and dirty monadic Nullable implementation for the C# Tasklike language proposal

What?

Running this C# code:

static void Main()
{
    var nullable = DoNullableThings();
    Console.WriteLine(nullable.HasValue);
    Console.ReadLine();
}

static async NullableTaskLike<int> DoNullableThings()
{
    var val1 = await GetValue();
    var val2 = await GetNoValue();

    var val3 = await GetValue();
    var val4 = await GetValue();
    var val5 = await GetValue();
    var val6 = await GetValue();
    var val7 = await GetValue();
    return val7;
}

static async NullableTaskLike<int> GetValue()
{
    Console.WriteLine("Returning 1");
    return 1;
}

static async NullableTaskLike<int> GetNoValue()
{
    Console.WriteLine("Returning none");
    return await new NullableTaskLike<int>();
}

produces this output:

Returning 1
Returning none
False

Wait, what?

Using the arbitrary async return C# language proposal (located here: https://github.com/ljw1004/roslyn/blob/features/async-return/docs/specs/feature%20-%20arbitrary%20async%20returns.md), we can return any task-like type we want from async methods. Using this, we can leverage the compiler to write code that acts like do-notation in Haskell. This implementation of Nullable is akin to Haskell's Maybe type.

If a NullableTaskLike method returns a concrete value then execution of the calling method proceeds after an await. However, if the method does not return a value (well, returns an empty NullableTaskLike) then execution of the method short circuits.

We can rewrite the above code to compiling C# 6 as:

static Nullable<int> DoNullableThings()
{
    var val1 = GetValue();
    if (!val1.HasValue) return val1;
    
    var val2 = await GetNoValue();
    if (!val2.HasValue) return val2;

    
    ... etc ...
    
    var val7 = await GetValue();
    if (!val7.HasValue) return val7;
    
    return val7;
}

Notes

In its current form, this is not compatible with asynchronous tasks.

About

Quick and dirty monadic Nullable implementation for the C# Tasklike language proposal

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages