Hello,

2011/4/8 Alain Frisch <alain.frisch@lexifi.com>
On 04/08/2011 10:20 AM, Jacques Garrigue wrote:
Applicative functors have other advantages, like the fact you can refer to a
type produced by a functor without having really applied it.

For instance think of the following functor definition

   module F(O : Set.OrderedType)(S : sig type t = Set.Make(O).t val union : t ->  t ->  t end) = ...

If you want to do the same thing with generative functors, I believe you have to
pass the result of Set.Make(O) around physically.
I do think this is a significant weakness.

I can imagine uses for:

module F(O : Set.OrderedType)(S : Set.S with type elt = O.t) =

but I don't see a real-life case where one would want functor F to know that the type S.t was really produced by applying Set.Make.  Do you have a specific example in mind?

I just try to compile Frama-C (http://frama-c.com) with the option -no-app-funct in order to discover where/why we need applicative functors (I knew that we use them somewhere).
I found three different patterns:

1) module M = F(G(X))

Without applicative functors, we get the error "The parameter cannot be eliminated in the result type. Please bind the argument to a module identifier.". That is easy to fix by introducing an intermediate module.

2) module F(X:...) = G(H(X))

Without applicative functors, we again get the error about parameter elimination. But I see no workaround to eliminate it without changing the signature of F. So IMHO that is a use case where applicative functors are useful.

3) type t = F(X).t
    type u = { a: t }
These declarations are in a single .mli file without a corresponding .ml file. G(X).t is an abstract type. Generators of values of type u are in a module F while users of type u are others modules. Also we have to solve an usual issue with mutual dependencies between F and its users. But the type u is one of the most useful type in Frama-C. Thus standard solution to the mutual dependencies issues which use polymorphism or functor are too heavy here. That is the lightweight solution that we found.

To summarize:
- case 1 may be easily solved by writting 2 lines of code instead of 1
- case 2 and 3 may be circumvented for sure, but the solutions that I have in mind are heavy

To conclude, there are only few use case where applicative functors are useful in an application like Frama-C (where there are thousands of functor applications). But IMHO that are enough cases to answer: yes applicative functors are (sometimes) useful.
 
--
Julien