In Functional Programming, what is a functor?

后端 未结 17 710
孤独总比滥情好
孤独总比滥情好 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:56

    There are three different meanings, not much related!

    • In Ocaml it is a parametrized module. See manual. I think the best way to grok them is by example: (written quickly, might be buggy)

      module type Order = sig
          type t
          val compare: t -> t -> bool
      end;;
      
      
      module Integers = struct
          type t = int
          let compare x y = x > y
      end;;
      
      module ReverseOrder = functor (X: Order) -> struct
          type t = X.t
          let compare x y = X.compare y x
      end;;
      
      (* We can order reversely *)
      module K = ReverseOrder (Integers);;
      Integers.compare 3 4;;   (* this is false *)
      K.compare 3 4;;          (* this is true *)
      
      module LexicographicOrder = functor (X: Order) -> 
        functor (Y: Order) -> struct
          type t = X.t * Y.t
          let compare (a,b) (c,d) = if X.compare a c then true
                               else if X.compare c a then false
                               else Y.compare b d
      end;;
      
      (* compare lexicographically *)
      module X = LexicographicOrder (Integers) (Integers);;
      X.compare (2,3) (4,5);;
      
      module LinearSearch = functor (X: Order) -> struct
          type t = X.t array
          let find x k = 0 (* some boring code *)
      end;;
      
      module BinarySearch = functor (X: Order) -> struct
          type t = X.t array
          let find x k = 0 (* some boring code *)
      end;;
      
      (* linear search over arrays of integers *)
      module LS = LinearSearch (Integers);;
      LS.find [|1;2;3] 2;;
      (* binary search over arrays of pairs of integers, 
         sorted lexicographically *)
      module BS = BinarySearch (LexicographicOrder (Integers) (Integers));;
      BS.find [|(2,3);(4,5)|] (2,3);;
      

    You can now add quickly many possible orders, ways to form new orders, do a binary or linear search easily over them. Generic programming FTW.

    • In functional programming languages like Haskell, it means some type constructors (parametrized types like lists, sets) that can be "mapped". To be precise, a functor f is equipped with (a -> b) -> (f a -> f b). This has origins in category theory. The Wikipedia article you linked to is this usage.

      class Functor f where
          fmap :: (a -> b) -> (f a -> f b)
      
      instance Functor [] where      -- lists are a functor
          fmap = map
      
      instance Functor Maybe where   -- Maybe is option in Haskell
          fmap f (Just x) = Just (f x)
          fmap f Nothing = Nothing
      
      fmap (+1) [2,3,4]   -- this is [3,4,5]
      fmap (+1) (Just 5)  -- this is Just 6
      fmap (+1) Nothing   -- this is Nothing
      

    So, this is a special kind of a type constructors, and has little to do with functors in Ocaml!

    • In imperative languages, it is a pointer to function.

提交回复
热议问题