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);
|
||||
expr t = d.get_type();
|
||||
check_pi(f, t);
|
||||
optional<name> C;
|
||||
buffer<name> Cs; // possible Cs
|
||||
while (is_pi(t)) {
|
||||
expr d = get_app_fn(binding_domain(t));
|
||||
if (is_constant(d))
|
||||
C = const_name(d);
|
||||
Cs.push_back(const_name(d));
|
||||
t = binding_body(t);
|
||||
}
|
||||
if (!C)
|
||||
if (Cs.empty())
|
||||
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) {
|
||||
|
|
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