feat(library/coercion): better support for coercions to function-class. closes #185
This commit is contained in:
parent
62585f1c56
commit
029acbd1df
2 changed files with 31 additions and 4 deletions
|
@ -344,16 +344,30 @@ environment add_coercion(environment const & env, name const & f, io_state const
|
||||||
declaration d = env.get(f);
|
declaration d = env.get(f);
|
||||||
expr t = d.get_type();
|
expr t = d.get_type();
|
||||||
check_pi(f, t);
|
check_pi(f, t);
|
||||||
optional<name> C;
|
buffer<name> Cs; // possible Cs
|
||||||
while (is_pi(t)) {
|
while (is_pi(t)) {
|
||||||
expr d = get_app_fn(binding_domain(t));
|
expr d = get_app_fn(binding_domain(t));
|
||||||
if (is_constant(d))
|
if (is_constant(d))
|
||||||
C = const_name(d);
|
Cs.push_back(const_name(d));
|
||||||
t = binding_body(t);
|
t = binding_body(t);
|
||||||
}
|
}
|
||||||
if (!C)
|
if (Cs.empty())
|
||||||
throw exception(sstream() << "invalid coercion, '" << f << "' cannot be used as a coercion");
|
throw exception(sstream() << "invalid coercion, '" << f << "' cannot be used as a coercion");
|
||||||
return add_coercion(env, f, *C, ios);
|
unsigned i = Cs.size();
|
||||||
|
while (i > 0) {
|
||||||
|
--i;
|
||||||
|
if (i == 0) {
|
||||||
|
// last alternative
|
||||||
|
return add_coercion(env, f, Cs[i], ios);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
return add_coercion(env, f, Cs[i], ios);
|
||||||
|
} catch (exception &) {
|
||||||
|
// failed, keep trying...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lean_unreachable(); // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<pair<name, unsigned>> is_coercion(environment const & env, name const & f) {
|
optional<pair<name, unsigned>> is_coercion(environment const & env, name const & f) {
|
||||||
|
|
13
tests/lean/run/coefun.lean
Normal file
13
tests/lean/run/coefun.lean
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
inductive obj (A : Type) :=
|
||||||
|
mk : A → obj A
|
||||||
|
|
||||||
|
inductive fn (A B : Type) :=
|
||||||
|
mk : (obj A → obj B) → fn A B
|
||||||
|
|
||||||
|
definition to_fun [coercion] {A B : Type} (f : fn A B) : obj A → obj B :=
|
||||||
|
fn.rec (λf, f) f
|
||||||
|
|
||||||
|
variable n : Type.{1}
|
||||||
|
variable f : fn n n
|
||||||
|
variable a : obj n
|
||||||
|
check (f a)
|
Loading…
Reference in a new issue