C
C#6mo ago
eid

can any one explain that?

Why is functor not an interface? If both Option and IEnumerable support the Map operation, why are we not capturing this with an interface? Indeed, it would be nice to do so, but unfortunately, it’s not possible in C#. To illustrate why, let’s try to define such an interface: interface Functor<F<>, T> { F<R> Map<R>(Func<T, R> f); } public struct Option<T> : Functor<Option, T> { public Option<R> Map<R>(Func<T, R> f) => // ... } This doesn’t compile: we can’t use F<> as a type variable because unlike T, it doesn’t indicate a type but rather a kind: a type that’s, in turn, parameterized with a generic type. And it’s not enough for Map to return a Functor. It must return a functor of the same kind as the current instance
4 Replies
Hazel 🌊💃
Hazel 🌊💃6mo ago
I'm a little confused about what you're trying to achieve and it feels like a design issue as a result. You state that your Map method must return the same type as the current instance but your definition in Option<T> violates this by returning Option<R> instead. My first thought is that what you're trying to achieve is something like this:
public interface IFunctor<TSelf, TIn>
where TSelf : IFunctor<TSelf, TIn>
{
TSelf Map<TOut>(Func<TIn, TOut> func);
}

public struct Option<T>
: IFunctor<Option<T>, T>
{
public Option<T> Map<TOut>(Func<T, TOut> func)
{
...
}
}
public interface IFunctor<TSelf, TIn>
where TSelf : IFunctor<TSelf, TIn>
{
TSelf Map<TOut>(Func<TIn, TOut> func);
}

public struct Option<T>
: IFunctor<Option<T>, T>
{
public Option<T> Map<TOut>(Func<T, TOut> func)
{
...
}
}
However, this deviates from your example in that you expect Option<TOut> instead of Option<T>. Can you try to clarify what you're hoping to achieve?
eid
eid6mo ago
In functional programming, a functor is a type that implements a map operation, allowing you to transform the values inside the functor while preserving its structure. The confusion seems to arise from the desire to return the same type as the current instance, but also expecting a transformed type.
Thinker
Thinker6mo ago
Why is functor not an interface?
The .NET type system doesn't support higher-kinded types, which are required to describe things like functors because they require "generic on generics", or this F<R> type. And on a more philosophical level, I don't think there would be much use from such an abstraction. Interfaces are absolutely useful to describe a lot of things, but I think an abstraction such as a functor wouldn't be very useful in C# specifically.
Thinker
Thinker6mo ago
Also there's actually a proposal for HKTs in .NET, but afaik it hasn't received much attention from the language team. https://github.com/dotnet/csharplang/issues/339
GitHub
Higher Kinded Polymorphism / Generics on Generics · Issue #339 · do...
@diab0l commented on Thu Apr 23 2015 tl;dr Haskell has monads Monads are like bacon C# needs bacon Introduction I have a mad craving for higher kinded polymorphism in C#. And I have no blog to call...