Coq - Coercion of list nat
Question
I would like to do a coercion from the type list nat to the type list bool. I would think that this could be done in the following way:
From Coq Require Import Lists.List.
Definition nat_to_bool (n : nat) : bool :=
match n with
| 0 => true
| _ => false
end.
Definition list_nat_to_list_bool (l : list nat) : list bool :=
map (fun n => (nat_to_bool n)) l.
Coercion list_nat_to_list_bool : list nat >-> list bool.
However, this doesn't work. It seems like there is a fundamental issue with using coercion on something of the form list nat. Why does this not work?
Answer
The documentation states that a class name must be a defined name. Neither list nat nor list bool are defined names - they are both applications. You must give the types between you want to define coercions a name as in:
From Coq Require Import Lists.List. Definition nat_to_bool (n : nat) : bool := match n with | 0 => true | _ => false end. Definition list_nat := list nat. Definition list_bool := list bool. Definition list_nat_to_list_bool (l : list_nat) : list_bool := map (fun n => (nat_to_bool n)) l. Coercion list_nat_to_list_bool : list_nat >-> list_bool.
Please note that the coercion function must use these names - you can't write list nat instead of list_nat. Also the applications of the coercion must use the defined names as in:
Definition test : list_bool := (1 :: nil) : list_nat.
I guess this is so because coercions might be done at the syntactic level where type unifications would be difficult.
Q: So, if I have a function f whose inputs are of type list bool, and I want to use coercion to pass objects of type list nat to it, I'd have to edit f so that its input type is list_bool instead? There isn't a way around this?
A: I am not an expert for coercions, but as far as I know and understand the documentation, that's how it is, yes.