Это своего рода продолжение моего предыдущего вопроса: Наследование нескольких классов типов в Coq , но речь идет о классах типов, которые ожидают разные типы (в терминах Haskell, я полагаю?).
У меня есть класс типов Collection, который ожидает Type -> Type
, и класс типов Monoid, который ожидает Type
, и я думал, что знаю, как согласовать их оба, но у меня проблемы с использованием функций Monoid.
Class Sequence (S : Type -> Type)
foldr empty insert append
`{C : Collection S foldr empty insert}
`{M : Monoid (forall A, S A) append empty} :=
{
insert_append_id :
forall (A : Type) (h : S A) (x : A),
append A (insert A x (empty A)) h = insert A x h
}.
И ошибка (усеченная):
Error:
In environment
Sequence :
forall (S : Type -> Type)
(append : (forall A : Type, S A) ->
(forall A : Type, S A) -> forall A : Type, S A)
[...]
S : Type -> Type
empty : forall A : Type, S A
append :
(forall A : Type, S A) -> (forall A : Type, S A) -> forall A : Type, S A
[...]
M : Monoid (forall A : Type, S A) append empty
A : Type
h : S A
x : A
The term "A" has type "Type" while it is expected to have type
"forall A : Type, S A".
Я думал, что был действительно умен, выясняя, что (forall A, S A)
в наследовании Monoid, но теперь я не так уверен. Тип Monoid empty
выглядит правильным, но тип append
для меня не имеет никакого смысла.
Мне кажется, что я либо ошибся с типом наследования Monoid, либо есть способ дать добавлению правильный тип, которого я не вижу. Или есть какая-то ошибка где-то еще, которая вызывает эту проблему?
Изменить: я придумал другое объявление Monoid, которое кажется ближе к тому, что я хочу, но все еще не работает.
Class Sequence (S : Type -> Type)
foldr empty insert (append : forall A, S A -> S A -> S A)
`{C : Collection S foldr empty insert}
`{M : forall (A : Type), Monoid (S A) (append A) (empty A)} :=
{
insert_append_eq :
forall (A : Type) (h : S A) (x : A),
append A (insert A x (empty A)) h = insert A x h
}.
И новая ошибка:
Error:
Could not find an instance for "Semigroup (S A) (append A)" in environment:
S : Type -> Type
foldr : forall A B : Type, (A -> B -> B) -> B -> S A -> B
empty : forall A : Type, S A
insert : forall A : Type, A -> S A -> S A
append : forall A : Type, S A -> S A -> S A
F : Foldable S foldr
U : Unfoldable S empty insert
C : Collection S foldr empty insert
A : Type