Is it possible to write a functor Interface for .NET?

后端 未结 2 781
故里飘歌
故里飘歌 2021-01-15 13:41

Functional languages often have Functor types/interfaces.

In .NET a Functor interface would be an Interface implementable by generic types (T)

相关标签:
2条回答
  • 2021-01-15 13:58

    The difficulty of giving a type to fmap is that it is parameterized by a higher-kinded type variable, the container type. So beyond being a simple polymorphic function, like say, map on lists:

    map :: (a -> b) -> List a -> List b
    

    fmap generalizes this to work on any container, as well as any element type:

    fmap :: Functor (f :: * -> *) => (a -> b) -> f a -> f b
    

    The problem in C# is that f is a higher-kinded type variable (it is a type function). Since C# doesn't support higher kinds, you'll be out of luck writing this directly, think.

    0 讨论(0)
  • 2021-01-15 14:12

    Okay, based on the comment, I suspect the answer's no - you'd need higher-order generic types. You'd want something like:

    // Not real syntax!
    interface IFunctor<TFunctor<?>, TValue>
        where TFunctor<X> : IFunctor<TFunctor<X>, TValue>
    {
        TFunctor<TProjection> Project<TProjection>(Func<TValue, TProjection> func);
    }
    

    The problem is trying to express the idea that the implementation of the interface must also be generic in a particular way, and allow that generic relationship to be used in the rest of the interface. That's not part of .NET generics, I'm afraid.

    Joe Duffy has written about wishing for higher-order types before now - unfortunately I can't tell whether or not that article is relevant, as I can't get to it at the moment. (His blog server is somewhat temporamently, but the content is great :)


    It's not entirely clear, but it's possible you're just talking about LINQ to Objects, basically. For example:

    var kids = people.Where(x => x.Age < 18) // Filtering
                     .Select(x => x.Name)    // Projection
                     .ToList();
    

    You could write a more general purpose interface, e.g.

    public interface IFunctor<T>
    {
        IFunctor<TOther> Foo<TOther>(Func<T, TOther> selector);
    }
    

    ... but there's no such interface actually implemented by List<T> etc. LINQ to Objects works via extension methods instead.

    0 讨论(0)
提交回复
热议问题