Idris 中的多参数 Sub-类
Multi-Parameter Sub-Classes in Idris
受到 this blog post and this code 的启发,我想我会在 Idris 中使用它的接口 (type-类) 尝试一些范畴理论。
我定义 Category
如下,效果很好:
interface Category (obj : Type) (hom : obj -> obj -> Type) where
id : {a : obj} -> hom a a
comp : {a, b, c : obj} -> hom b c -> hom a b -> hom a c
然后,本着 Verified
模块的精神,我想定义一个经过验证的类别:
interface Category obj hom =>
VerifiedCategory (obj : Type) (hom : obj -> obj -> Type) where
categoryAssociativity : {a, b, c, d : obj} ->
(f : hom c d) -> (g : hom b c) -> (h : hom a b) ->
(comp (comp f g) h = comp f (comp g h))
categoryLeftIdentity : {a, b : obj} -> (f : hom a b) -> (comp id f = f)
categoryRightIdentity : {a, b : obj} -> (f : hom a b) -> (comp f id = f)
不幸的是,Idris 拒绝该代码并显示以下错误消息:
When checking type of constructor of CategoryTheory.VerifiedCategory:
Can't find implementation for Category obj hom
我是不是做错了什么,或者我是在尝试做一些 Idris 做不到的多参数子类?
所有这些代码都在它自己的模块中,称为 CategoryTheory
,没有任何导入。
我正在使用 Idris v0.12。
我不知道为什么(并且很想知道!)但是如果您在 VerifiedCategory
中指定 id
和 comp
的所有隐式参数,它就会起作用明确地。弄清楚它是非常丑陋和乏味的,但是这个类型检查:
interface Category obj hom => VerifiedCategory (obj : Type) (hom : obj -> obj -> Type) where
categoryAssociativity : {a, b, c, d : obj} ->
(f : hom c d) ->
(g : hom b c) ->
(h : hom a b) ->
(comp {a = a} {b = b} {c = d} (comp {a = b} {b = c} {c = d} f g) h = comp {a = a} {b = c} {c = d} f (comp {a = a} {b = b} {c = c} g h))
categoryLeftIdentity : {a, b : obj} ->
(f : hom a b) ->
(comp {a = a} {b = b} {c = b} (id {a = b}) f = f)
categoryRightIdentity : {a, b : obj} ->
(f : hom a b) ->
(comp {a = a} {b = a} {c = b} f (id {a = a}) = f)
编辑:我刚刚找到的另一种方法是将hom
明确指定为determining parameter,即class类型的参数这足以找到一个实现。这必须发生在 Category
以及 VerifiedCategory
中(我不确定,为什么),像这样:
interface Category (obj : Type) (hom : obj -> obj -> Type) | hom where
-- ...
interface Category obj hom => VerifiedCategory (obj : Type) (hom : obj -> obj -> Type) where
-- ...
即通过在 where
.
之前放置 | hom
除此之外,您还必须做的一件事是限定 id
在 VerifiedCategory
中的使用,否则无论出于何种原因,它都会被解释为隐式参数:
categoryLeftIdentity : {a, b : obj} ->
(f : hom a b) ->
comp CategoryTheory.id f = f
categoryRightIdentity : {a, b : obj} ->
(f : hom a b) ->
comp f CategoryTheory.id = f
另请参阅 this reddit 线程,它可能会在未来有所启发。
受到 this blog post and this code 的启发,我想我会在 Idris 中使用它的接口 (type-类) 尝试一些范畴理论。
我定义 Category
如下,效果很好:
interface Category (obj : Type) (hom : obj -> obj -> Type) where
id : {a : obj} -> hom a a
comp : {a, b, c : obj} -> hom b c -> hom a b -> hom a c
然后,本着 Verified
模块的精神,我想定义一个经过验证的类别:
interface Category obj hom =>
VerifiedCategory (obj : Type) (hom : obj -> obj -> Type) where
categoryAssociativity : {a, b, c, d : obj} ->
(f : hom c d) -> (g : hom b c) -> (h : hom a b) ->
(comp (comp f g) h = comp f (comp g h))
categoryLeftIdentity : {a, b : obj} -> (f : hom a b) -> (comp id f = f)
categoryRightIdentity : {a, b : obj} -> (f : hom a b) -> (comp f id = f)
不幸的是,Idris 拒绝该代码并显示以下错误消息:
When checking type of constructor of CategoryTheory.VerifiedCategory:
Can't find implementation for Category obj hom
我是不是做错了什么,或者我是在尝试做一些 Idris 做不到的多参数子类?
所有这些代码都在它自己的模块中,称为 CategoryTheory
,没有任何导入。
我正在使用 Idris v0.12。
我不知道为什么(并且很想知道!)但是如果您在 VerifiedCategory
中指定 id
和 comp
的所有隐式参数,它就会起作用明确地。弄清楚它是非常丑陋和乏味的,但是这个类型检查:
interface Category obj hom => VerifiedCategory (obj : Type) (hom : obj -> obj -> Type) where
categoryAssociativity : {a, b, c, d : obj} ->
(f : hom c d) ->
(g : hom b c) ->
(h : hom a b) ->
(comp {a = a} {b = b} {c = d} (comp {a = b} {b = c} {c = d} f g) h = comp {a = a} {b = c} {c = d} f (comp {a = a} {b = b} {c = c} g h))
categoryLeftIdentity : {a, b : obj} ->
(f : hom a b) ->
(comp {a = a} {b = b} {c = b} (id {a = b}) f = f)
categoryRightIdentity : {a, b : obj} ->
(f : hom a b) ->
(comp {a = a} {b = a} {c = b} f (id {a = a}) = f)
编辑:我刚刚找到的另一种方法是将hom
明确指定为determining parameter,即class类型的参数这足以找到一个实现。这必须发生在 Category
以及 VerifiedCategory
中(我不确定,为什么),像这样:
interface Category (obj : Type) (hom : obj -> obj -> Type) | hom where
-- ...
interface Category obj hom => VerifiedCategory (obj : Type) (hom : obj -> obj -> Type) where
-- ...
即通过在 where
.
| hom
除此之外,您还必须做的一件事是限定 id
在 VerifiedCategory
中的使用,否则无论出于何种原因,它都会被解释为隐式参数:
categoryLeftIdentity : {a, b : obj} ->
(f : hom a b) ->
comp CategoryTheory.id f = f
categoryRightIdentity : {a, b : obj} ->
(f : hom a b) ->
comp f CategoryTheory.id = f
另请参阅 this reddit 线程,它可能会在未来有所启发。