In Functional Programming, what is a functor?

后端 未结 17 580
孤独总比滥情好
孤独总比滥情好 2020-11-28 17:23

I\'ve come across the term \'Functor\' a few times while reading various articles on functional programming, but the authors typically assume the reader already understands

相关标签:
17条回答
  • 2020-11-28 17:48

    Put simply, a functor, or function object, is a class object that can be called just like a function.

    In C++:

    This is how you write a function

    void foo()
    {
        cout << "Hello, world! I'm a function!";
    }
    

    This is how you write a functor

    class FunctorClass
    {
        public:
        void operator ()
        {
            cout << "Hello, world! I'm a functor!";
        }
    };
    

    Now you can do this:

    foo(); //result: Hello, World! I'm a function!
    
    FunctorClass bar;
    bar(); //result: Hello, World! I'm a functor!
    

    What makes these so great is that you can keep state in the class - imagine if you wanted to ask a function how many times it has been called. There's no way to do this in a neat, encapsulated way. With a function object, it's just like any other class: you'd have some instance variable that you increment in operator () and some method to inspect that variable, and everything's neat as you please.

    0 讨论(0)
  • 2020-11-28 17:49

    Here's an article on functors from a programming POV, followed up by more specifically how they surface in programming languages.

    The practical use of a functor is in a monad, and you can find many tutorials on monads if you look for that.

    0 讨论(0)
  • 2020-11-28 17:52

    Other answers here are complete, but I'll try another explanation of the FP use of functor. Take this as analogy:

    A functor is a container of type a that, when subjected to a function that maps from ab, yields a container of type b.

    Unlike the abstracted-function-pointer use in C++, here the functor is not the function; rather, it's something that behaves consistently when subjected to a function.

    0 讨论(0)
  • 2020-11-28 17:53

    There is a pretty good example in the O'Reilly OCaml book that's on Inria's website (which as of writing this is unfortunately down). I found a very similar example in this book used by caltech: Introduction to OCaml (pdf link). The relevant section is the chapter on functors (Page 139 in the book, page 149 in the PDF).

    In the book they have a functor called MakeSet which creates a data structure that consists of a list, and functions to add an element, determine if an element is in the list, and to find the element. The comparison function that is used to determine if it's in/not in the set has been parametrized (which is what makes MakeSet a functor instead of a module).

    They also have a module that implements the comparison function so that it does a case insensitive string compare.

    Using the functor and the module that implements the comparison they can create a new module in one line:

    module SSet = MakeSet(StringCaseEqual);;
    

    that creates a module for a set data structure that uses case insensitive comparisons. If you wanted to create a set that used case sensitive comparisons then you would just need to implement a new comparison module instead of a new data structure module.

    Tobu compared functors to templates in C++ which I think is quite apt.

    0 讨论(0)
  • 2020-11-28 17:53

    Given the other answers and what I'm going to post now, I'd say that it's a rather heavily overloaded word, but anyway...

    For a hint regarding the meaning of the word 'functor' in Haskell, ask GHCi:

    Prelude> :info Functor
    class Functor f where
      fmap :: forall a b. (a -> b) -> f a -> f b
      (GHC.Base.<$) :: forall a b. a -> f b -> f a
            -- Defined in GHC.Base
    instance Functor Maybe -- Defined in Data.Maybe
    instance Functor [] -- Defined in GHC.Base
    instance Functor IO -- Defined in GHC.Base
    

    So, basically, a functor in Haskell is something that can be mapped over. Another way to say it is that a functor is something which can be regarded as a container which can be asked to use a given function to transform the value it contains; thus, for lists, fmap coincides with map, for Maybe, fmap f (Just x) = Just (f x), fmap f Nothing = Nothing etc.

    The Functor typeclass subsection and the section on Functors, Applicative Functors and Monoids of Learn You a Haskell for Great Good give some examples of where this particular concept is useful. (A summary: lots of places! :-))

    Note that any monad can be treated as a functor, and in fact, as Craig Stuntz points out, the most often used functors tend to be monads... OTOH, it is convenient at times to make a type an instance of the Functor typeclass without going to the trouble of making it a Monad. (E.g. in the case of ZipList from Control.Applicative, mentioned on one of the aforementioned pages.)

    0 讨论(0)
  • 2020-11-28 17:53

    In practice, functor means an object that implements the call operator in C++. In ocaml I think functor refers to something that takes a module as input and output another module.

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