fmap/bind and/or LINQ support for nullable types #3607
Replies: 10 comments
-
To sum up, you're looking for the ability to define extension methods that would be applicable only to instances of a nullable reference type? I think that would be a bit complicated as despite being called "Nullable Reference Types" they're not actual types and the nullability can flip based on usage. So, my questions would be:
|
Beta Was this translation helpful? Give feedback.
-
Using extension methods would be one of the two ways I was thinking of, but I actually was not arguing for user-defined extension methods, only internally pre-defined Select/SelectMany extensions. The other way I propose is to translate LINQ queries for nullables differently, namely into if-cascades (or ternary operator cascades). Regarding your questions:
|
Beta Was this translation helpful? Give feedback.
-
Those methods would be coming from the BCL and they can't be conditionally defined in such a manner. Either a class has the method or it doesn't. IMO NRTs aren't a good way to model |
Beta Was this translation helpful? Give feedback.
-
You are right, ADTs are the obvious solution and I’m hyped for them. I wanted to tackle the problem of “legacy” (non-ADT) code here. Let’s assume we had ADTs, would there be a way to promote T? to Option<T>, either automatically or manually (but in a concise way without clutter)? |
Beta Was this translation helpful? Give feedback.
-
Theoretically, yes, you should be able to define an implicit conversion to one. You might start to run into some odd corners around interfaces however, as user defined conversions do not apply to interface types. A better solution might be an extension |
Beta Was this translation helpful? Give feedback.
-
I think this is already possible, see this example using System;
#nullable enable
public class C {
public void M() {
string? maybeS = null;
string f(string x) => x.ToUpper();
var result = from s in maybeS
select f(s);
var result2 = f(maybeS); // CS8604: Possible null reference argument for parameter
}
}
public static class Extensions
{
public static TRet? Select<T, TRet>(this T? input, Func<T, TRet> selector)
where T : class where TRet : class
{
if (input is null)
return default;
return selector(input);
}
} |
Beta Was this translation helpful? Give feedback.
-
That does work, but it doesn't limit the extension method to cases where the variable is maybe- |
Beta Was this translation helpful? Give feedback.
-
It compiles when you are |
Beta Was this translation helpful? Give feedback.
-
You're right I was speaking too fast, I'm sorry. Let me think about whether there are other potential ambiguities. |
Beta Was this translation helpful? Give feedback.
-
The following strikes me as counter-intuitive: // with using System.Linq;
IEnumerable<int> xs = new int[2] {1,2};
var ys = xs.Select(x => new [] {x}); // type IEnumerable<int>[]? instead of IEnumerable<int[]> |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi,
I tend to think of nullable types as option types (
Maybe T
in Haskell,T option
in F#, etc.).While for nullable value types we can add extension methods, nullable reference types are a language feature instead of a type, thus we cannot offer functor/monad functionality via
Select
andSelectMany
methods (which would yield automatic LINQ support as well).One of the strengths of option types is to ignore the possibility of a missing value and perform calculations via functorial map, until the value is actually needed at which point now I have to deal with possibly missing values (a
GetOrElse
method would also be a nice addition to nullable reference types here by the way).The same holds for operations in between that also may fail (
T -> T?
typed), which are applied via monadic bind.I'm new to C# language discussions, so I'm not sure what is the best way to achieve this.
One could 1:1 map the language feature to a type (which should offer similar methods as
Option<T>
from language-ext), or without mapping it to a type, special LINQ support could be enabled for nullable reference types.I would envision something like this
Which can be translated into
Select
/SelectMany
just as any other LINQ query, if we map to a type. If we choose to not map to a type these queries should translate intoLooking forward to your opinions.
Beta Was this translation helpful? Give feedback.
All reactions