我正在尝试在Idris中编写一个库来处理类别和函子。对于我的用例,每种类型最多只能以一种方式成为类别(我想对id
和.
使用重载),因此使用接口可以满足我的需求:
infixr 9 .
interface CategoryI (o : Type) where
data Hom : o -> o -> Type
(.) : {a : o} -> {b : o} -> {c : o} -> Hom b c -> Hom a b -> Hom a c
id : (a : o) -> Hom a a
但是,对于函子,我需要一个数据类型而不是一个接口,因为在我要考虑的同一两个类别之间可以有多个函子。
data Functor : Type -> Type -> Type where
MkFunctor : (CategoryI s, CategoryI t) =>
(f : s -> t)
-> (Hom x y -> Hom (f x) (f y))
-> Functor s t
要利用这一点,我编写了访问器功能:
src : Functor s t -> Type
src (MkFunctor fo fm) = s
tgt : Functor s t -> Type
tgt (MkFunctor fo fm) = t
f_obj : (CategoryI s, CategoryI t) => Functor s t -> (s -> t)
f_obj (MkFunctor fo fm) = fo
但是我遇到以下问题:
f_map : (CategoryI s, CategoryI t) => (f : Functor s t)
-> (Hom x y -> Hom ((f_obj f) x) ((f_obj f) y))
f_map (MkFunctor fo fm) = fm
编译器抱怨:
When checking right hand side of f_map with expected type
Hom x y -> Hom (f_obj (MkFunctor fo fm) x) (f_obj (MkFunctor fo fm) y)
Type mismatch between
Hom x y -> Hom (fo x) (fo y) (Type of fm x y)
and
Hom x y -> Hom (fo x) (fo y) (Expected type)
Specifically:
Type mismatch between
constraint1
and
constraint
在这里我什至无法确定编译器在抱怨什么。 IT不能以某种方式统一两个约束(哪个约束?),但是我的构造函数和f_map
函数上的约束是相同的,所以我看不出问题出在哪里。
如何解决此问题?