You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
First, the applicativity of functors can be broken by using submodules : two applications of the same (applicative) functor to the same argument produce incompatible (yet concrete) types. This comes from the fact that the submodules inside a functor are actually "generative", every application create a new submodule not equal to the others.
A minimal example would be the following :
moduleF (_: sig end) =structtype t endmoduleG (_: sig end) =structmoduleY=structend(* identity of Y is generative *)typeu = F(Y).t (* actually generative *)endmoduleX0=structendmoduleX1=G(X0)
moduleX2=G(X0)
letf (x:X1.u) = (x:X2.u) (* fails ! *)
It is caused by the lack of a mechanism to track arbitrary aliases between modules (i.e. general transparent ascription), and might be impossible to fix without (?)
Incorrect strengthening
Strengthening is used to rewrite type equality in a signature resulting from a functor application. However, it does so assuming that abstract types are always applicative, i.e. that adding type equalities/manifests is always correct. When using datatypes, this can lead to a situation where two different type definitions being are considered equal while having different constructors, which is is invalid. The signature returned by the typechecker is not wellformed. This can be seen by slightly adapting the previous example :
moduleF (_: sig end) =structtype t endmoduleG (_: sig end) =structmoduleY=structend(* identity of Y is generative *)typeu = F(Y).t (* actually generative *)typev = Entryofu(* also generative, but will be strengthened ! (making it applicative) *)endmoduleX0=structendmoduleX1=B(X0)
moduleX2=B(X0)
This gives :
moduleX1 :
sigmoduleY : sigendtype u =F(Y).t type v =B(X0).v =A of u endmoduleX2 :
sigmoduleY : sigendtype u =F(Y).t type v =X1.v =A of u end
which is incorrect as X1.v and X2.v are equal but with different constructors (as X1.u and X2.u are not equal)
This could be fixed by re-checking the signature after strengthening, but that seems overkill (and costly). An other option would be to try to identify which types inside an applicative functor are actually generative, and prevent strengthening when they appear in the constructors of a datatype. It seems hard and fragile.
The text was updated successfully, but these errors were encountered:
This issue is in two parts, and was discovered by investigating this bug with recursive modules
Loss of applicativity with submodules
First, the applicativity of functors can be broken by using submodules : two applications of the same (applicative) functor to the same argument produce incompatible (yet concrete) types. This comes from the fact that the submodules inside a functor are actually "generative", every application create a new submodule not equal to the others.
A minimal example would be the following :
It is caused by the lack of a mechanism to track arbitrary aliases between modules (i.e. general transparent ascription), and might be impossible to fix without (?)
Incorrect strengthening
Strengthening is used to rewrite type equality in a signature resulting from a functor application. However, it does so assuming that abstract types are always applicative, i.e. that adding type equalities/manifests is always correct. When using datatypes, this can lead to a situation where two different type definitions being are considered equal while having different constructors, which is is invalid. The signature returned by the typechecker is not wellformed. This can be seen by slightly adapting the previous example :
This gives :
which is incorrect as
X1.v
andX2.v
are equal but with different constructors (asX1.u
andX2.u
are not equal)This could be fixed by re-checking the signature after strengthening, but that seems overkill (and costly). An other option would be to try to identify which types inside an applicative functor are actually generative, and prevent strengthening when they appear in the constructors of a datatype. It seems hard and fragile.
The text was updated successfully, but these errors were encountered: