Zulip Chat Archive
Stream: general
Topic: typeclass loop in lift_lift and option
Eric Wieser (Oct 01 2021 at 11:05):
This hits a typeclass search loop:
prelude
import init.coe
set_option trace.class_instances true
set_option class.instance_max_depth 50
/- without this line, we hit a typeclass search loop for
`has_lift_t (list (with_zero (with_zero ... (with_zero ℕ)))) (cycle ℕ)` -/
-- local attribute [-instance] lift_list
example : ℕ := ↑[(1 : ℕ)]
Eric Wieser (Oct 01 2021 at 11:08):
It ends up looking for a stupid instance like
(list (option (option (option (option (option (option (option (option (option (option (option (option ℕ)))))))))))))
ℕ :=
where the number of option
s is bounded only by the max depth
Eric Wieser (Oct 01 2021 at 11:08):
This only gets worse without the prelude
, as widget.html
and with_zero
also join the game
Reid Barton (Oct 01 2021 at 11:09):
interestingly
https://github.com/leanprover-community/lean/blob/a0fb1e8c7ac81dfd2e80ad0de08f4e57ee853d82/library/init/coe.lean#L105
Reid Barton (Oct 01 2021 at 11:19):
Ah this is really about lift_list
Eric Wieser (Oct 01 2021 at 11:22):
Right, one of docs#lift_list and docs#coe_option is to blame here, unless the transitivity mechanism itself is flawed. I guess that's also quite possible, given Lean4 chose to design it differently.
Kevin Buzzard (Oct 01 2021 at 11:56):
Just to be clear -- you're not expecting such a coercion to exist right?
Eric Wieser (Oct 01 2021 at 12:26):
No, I'm not expecting it to exist, that would be nonsense!
Floris van Doorn (Oct 02 2021 at 07:09):
In docs#lift_list we should probably either
- replace the type-class assumption from
[has_lift_t a b]
to[has_lift a b]
; or - replace the conclusion from
has_lift (list a) (list b)
tohas_lift_t (list a) (list b)
Eric Wieser (Oct 02 2021 at 08:00):
Should we have an instance for both cases?
Floris van Doorn (Oct 04 2021 at 08:07):
That seems unnecessary. I think the instance [has_lift a b] : has_lift (list a) (list b)
is fully general, since we can do docs#lift_trans on the list
level (e.g. if we have lifts a -> b
and b -> c
which gives lifts list a -> list b
and list b -> list c
so we get a has_lift_t (list a) (list c)
).
Floris van Doorn (Oct 04 2021 at 08:10):
Last updated: Dec 20 2023 at 11:08 UTC