Search code examples
listtypescoqcoercion

Coq - Coercion of list nat


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?


Solution

  • 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.