Consider the following code in C#.
public int Foo(int a)
{
// ...
}
// in some other method
int? x = 0;
x = Foo(x);
The last line will return a compilation error cannot convert from 'int?' to 'int'
which is fair enough. However, for example in Haskell there is Maybe
which is a counterpart to Nullable
in C#. Since Maybe
is a Functor
I would be able to apply Foo
to x
using fmap
. Does C# have a similar mechanism?
We can implement such functionality ourselves:
public static class FuncUtils {
public static Nullable<R> Fmap<T, R>(this Nullable<T> x, Func<T, R> f)
where T : struct
where R : struct {
if(x != null) {
return f(x.Value);
} else {
return null;
}
}
}
Then we can use it with:
int? x = 0;
x = x.Fmap(Foo);
It will thus call the function Foo
if x
is not null
. It will wrap the result back in a Nullable<R>
. In case x
is null
, it will return a Nullable<R>
with null
.
Or we can write a more equivalent function (like fmap
in Haskell) where we have a function Fmap
that takes as input a Func<T, R>
and returns a Func<Nullable<T>, Nullable<R>>
so that we can then use it for a certain x
:
public static class FuncUtils {
public static Func<Nullable<T>, Nullable<R>> Fmap<T, R>(Func<T, R> f)
where T : struct
where R : struct {
return delegate (Nullable<T> x) {
if(x != null) {
return f(x.Value);
} else {
return null;
}
};
}
}
We can then use it like:
var fmapf = FuncUtils.Fmap<int, int>(Foo);
fmapf(null); // -> null
fmapf(12); // -> Foo(12) as int?