Closed jadephilipoom closed 3 years ago
This change breaks compilation in coq -freespec-core
and coq-parsec
:
#=== ERROR while compiling coq-parsec.dev =====================================#
# context 2.0.7 | linux/x86_64 | ocaml-base-compiler.4.05.0 | https://coq.inria.fr/opam/extra-dev#2021-01-14 10:00
# path ~/.opam/4.05.0/.opam-switch/build/coq-parsec.dev
# command /usr/bin/make -j2
# exit-code 2
# env-file ~/.opam/log/coq-parsec-2355-ac853a.env
# output-file ~/.opam/log/coq-parsec-2355-ac853a.out
### output ###
# - ?Monad1: Cannot infer the implicit parameter Monad of ret whose type is
# [...]
# H : Serialize P
# H0 : forall p q : P, Decidable (p = q)
# xs : list P
# x : P
# xs' : list P
# u : unit
#
# make[2]: *** [Makefile.coq:716: theories/Parser.vo] Error 1
# make[1]: *** [Makefile.coq:339: all] Error 2
# make[1]: Leaving directory '/home/coq/.opam/4.05.0/.opam-switch/build/coq-parsec.dev'
# make: *** [Makefile:4: all] Error 2
#=== ERROR while compiling coq-freespec-core.dev ==============================#
# context 2.0.7 | linux/x86_64 | ocaml-base-compiler.4.05.0 | https://coq.inria.fr/opam/extra-dev#2021-01-14 10:00
# path ~/.opam/4.05.0/.opam-switch/build/coq-freespec-core.dev
# command ~/.opam/4.05.0/bin/dune build -p coq-freespec-core -j 2
# exit-code 1
# env-file ~/.opam/log/coq-freespec-core-2355-2e72e2.env
# output-file ~/.opam/log/coq-freespec-core-2355-2e72e2.out
### output ###
# [...]
# - ?Monad1: Cannot infer the implicit parameter Monad of ret whose type is
# "Monad (instrument Ω ix)" (no type class instance found) in
# environment:
# ix, i : interface
# H : MayProvide ix i
# Ω : Type
# c : contract i Ω
# a : Type
# e : ix a
# x : a
# y : Ω
#
<><> Error report <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
+- The following actions failed
| - build coq-freespec-core dev
| - build coq-parsec dev
Minimal failing example:
From ExtLib Require Import
Monad
OptionMonad
StateMonad.
Fail Definition foo : stateT unit option unit :=
ret tt.
The command has indeed failed with message: Unable to satisfy the following constraints:
?Monad : "Monad (stateT unit option)"
These failures can be fixed with Existing Instance Monad_stateT
; it's up to the regular maintainers whether it's worse to require users of stateT
to write Existing Instance
or to cause the infinite-looping problem in certain setups for anyone who imports StateMonad
(even transitively). If you feel it is not worth the change, I'll just close the PR.
I can add that line to Parsec immediately. Will merge if FreeSpec accepts that line as well.
Also, could you document this requirement of Existing Instance
by (1) commenting above the line you changed, and (2) adding a code snippet under examples
directory?
Comment and example are now added!
That's a pretty far-reaching change. I don't have a concrete objection but it does raise some questions:
Set Typeclasses eauto := <depth>
- Does this practice exist in other projects?
I've been on a couple of Coq projects with the rule to avoid Global Instance wherever possible, because it makes it hard for importers to control typeclass resolution.
- How does it compare to bounding the type class search depth with Set Typeclasses eauto :=
I'd rather not do this for my use case, since typeclass resolution can for legitimate reasons go fairly deep and this could make resolution unpredictable, where some cases requiring a deep search fail to unify.
First, thank you for monitoring your dependencies to check whether or not they breaks with PR. This is really neat!
I was a bit surprised to see the content of your PR, and wonder if a different approach would be to put this instance in its own, dedicated module (similarly to what has been done in coq-simple-io
for MonadFix
). It would be paired with the appropriate warning about its danger.
and wonder if a different approach would be to put this instance in its own, dedicated module (similarly to what has been done in
coq-simple-io
forMonadFix
)
That solution would also work just fine for me! Is it preferred?
I personnally would find this less cumbersome. I feel like Existing Instance
is way more “arcane” compared to importing a module.
What needs to be done for this PR (or some alternative solution) to be merged?
That's up to @liyishuai, but as another user I think this can just be merged. Even though some of us are apprehensive about this different way of doing things, the motivation is sound and I the trade-off seems worth it.
I just merged your PR in FreeSpec, so you can move forward with this :). Thanks again for the heads up!
Propose merging on Wednesday if no more concerns arise.
Because
Monad_stateT
requires a monad argument, it can in some situations create infinite loops in typeclass resolution. My minimized example of the problem:The
hangs
definition is not properly typed (it has typem (m (proj 1)
), but I'd still prefer to get a typeclass-resolution error here than to get an infinite loop. The trace fromTypeclasses Debug
is:Removing the
Global
modifier fromMonad_stateT
locally fixes this issue for me, giving me the expected typeclass resolution error instead of the infinite loop. Although the rest of theMonad
instances areGlobal
, I think that it might make sense to make an exception for this one.