Есть ли способ использовать рекурсию с классами типов Coq?Как, например, при определении show для списков, если вы хотите рекурсивно вызывать функцию show
для списков, вам придется использовать точку фиксирования, например, так:
Require Import Strings.String.
Require Import Strings.Ascii.
Local Open Scope string_scope.
Class Show (A : Type) : Type :=
{
show : A -> string
}.
Section showNormal.
Instance showList {A : Type} `{Show A} : Show (list A) :=
{
show :=
fix lshow l :=
match l with
| nil => "[]"
| x :: xs => show x ++ " : " ++ lshow xs
end
}.
End showNormal.
Что все хорошо, но что, если я хочу определить некоторую вспомогательную функцию, которую я буду использовать для определения Show
экземпляров?Как я хочу создать еще одну функцию показа DAZZLING, которая называется magicShow
, которая печатает звезды вокруг чего-либо ...
Definition magicShow {A : Type} `{Show A} (a : A) : string :=
"** " ++ show a ++ " **".
Instance showMagicList {A : Type} `{Show A} : Show (list A) :=
{
show :=
fix lshow l :=
match l with
| nil => "[]"
| x :: xs => show x ++ " : " ++ magicShow xs
end
}.
Однако в этом случае Coq не может найти экземпляр шоу для списка xs
перейти на magicShow
:
Error:
Unable to satisfy the following constraints:
In environment:
A : Type
H : Show A
lshow : list A -> string
l : list A
x : A
xs : list A
?H : "Show (list A)"
Есть ли способ сделать это вообще?То есть, вы можете определить метод для класса типов, используя функции, которые полагаются на экземпляр класса типов, который вы определяете?