Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Applicative vs Generative functors

I have recently been learning SML, when I came to know the terms - applicative and generative functors. I also know that SML uses generative functors.

I tried to Google the terms but couldn't find any compelling resources that explains what these terms mean and what are the differences between the two.

So, I just wanted to know the actual meaning of these terms in some practically understable way and how this relates to SML being generative.

like image 963
him Avatar asked Sep 04 '18 07:09

him


People also ask

Is applicative a functor?

Applicative functors are the programming equivalent of lax monoidal functors with tensorial strength in category theory. Applicative functors were introduced in 2008 by Conor McBride and Ross Paterson in their paper Applicative programming with effects.

Is maybe an applicative functor?

Maybe is also an applicative functor, but more exist. The next article will give you another example. Next: Applicative validation.


1 Answers

It has to do with equality of abstract types in the module resulting from functor application.

Generative means that two invocations of a functor will produce modules containing non-equal abstract types.

Applicative means that two invocations of a functor will produce modules containing equal abstract types if the arguments are equal in some sense (such as being syntactically identical).

I'll give an example in OCaml, since it happens to support both:

module App (M : sig end) : sig
  type t
  val zero : t
end = struct
  type t = int
  let zero = 0
end

(* A () argument signifies a generative functor in OCaml. *)
module Gen (M : sig end) () : sig
  type t
  val zero : t
end = struct
  type t = int
  let zero = 0
end

module Empty = struct end

module A = App (Empty)
module B = App (Empty)
module C = App (struct end) (* The argument is syntactically different. *)

module D = Gen (Empty) ()
module E = Gen (Empty) ()

let _ = begin
  (* A.t and B.t are compatible. *)
  ignore (A.zero = B.zero);  (* OK *)

  (* A.t and C.t are not compatible because the functor arguments
   * are not syntactically equal. *)
  ignore (A.zero = C.zero);  (* type error *)

  (* D.t and C.t are not compatible because they are produced
   * from generative functors. *)
  ignore (D.zero = E.zero); (* type error *)
end
like image 65
gsg Avatar answered Nov 12 '22 17:11

gsg