有可能代表如何使unFix
总计?可能通过限制f
是什么?
record Fix (f : Type -> Type) where
constructor MkFix
unFix : f (Fix f)
> :total unFix
Fix.unFix is possibly not total due to:
MkFix, which is not strictly positive
答案 0 :(得分:7)
这里的问题是Idris无法知道您用于数据类型的基本函子严格为正。如果要接受您的定义,则可以将其与具体的负函子一起使用,并从中证明Void
。
有两种方法表示严格的正函子:通过定义Universe或使用容器。我已将所有内容都放在two self-contained gists中(但那里没有评论)。
您可以从基本表示开始:我们可以将函子分解为sigma类型(Sig
),递归子结构(Rec
)的(严格正值)位置或不分解为全部(End
)。这为我们提供了此描述及其作为Type -> Type
函数的解码:
-- A universe of positive functor
data Desc : Type where
Sig : (a : Type) -> (a -> Desc) -> Desc
Rec : Desc -> Desc
End : Desc
-- The decoding function
desc : Desc -> Type -> Type
desc (Sig a d) x = (v : a ** desc (d v) x)
desc (Rec d) x = (x, desc d x)
desc End x = ()
一旦您拥有此函子的范围,并且保证它们是严格肯定的,就可以采用其最小定点:
-- The least fixpoint of such a positive functor
data Mu : Desc -> Type where
In : desc d (Mu d) -> Mu d
您现在可以定义自己喜欢的数据类型。
我们从每个构造函数的标签的总和类型开始。
data NatC = ZERO | SUCC
然后,通过将构造函数标签存储在sigma中并基于标签值计算其余描述,来定义严格的正基函子。 ZERO
标记与End
相关联(zero
构造函数中没有其他可存储的东西),而SUCC
则需要一个Rec End
,即说一个与Nat的前任相对应的递归子结构。
natD : Desc
natD = Sig NatC $ \ c => case c of
ZERO => End
SUCC => Rec End
然后通过获取描述的固定点来获得我们的归纳类型:
nat : Type
nat = Mu natD
我们自然可以恢复我们期望的构造函数:
zero : nat
zero = In (ZERO ** ())
succ : nat -> nat
succ n = In (SUCC ** (n, ()))
这个特定的宇宙来自McBride的“装饰代数,代数装饰”,但您可以在Chapman,Dagand,McBride和Morris的“ The Livitation of Levitation”中找到更多详细信息。
第二种表示形式是基于另一种分解的:每个归纳类型都被视为一般形状(即其构造函数和它们存储的数据)加上许多递归位置(这可能取决于形状的特定值)。
record Container where
constructor MkContainer
shape : Type
position : shape -> Type
再一次,我们可以将其解释为Type -> Type
函数:
container : Container -> Type -> Type
container (MkContainer s p) x = (v : s ** p v -> x)
并使用由此定义的严格正函子的固定点:
data W : Container -> Type where
In : container c (W c) -> W c
通过定义感兴趣的Container
,您可以再次恢复自己喜欢的数据类型。
自然数有两个构造函数,每个构造函数根本不存储任何内容。因此形状将为Bool
。如果我们处于zero
情况下,则没有递归位置(Void
),而在succ
中有一个递归位置(()
)。
natC : Container
natC = MkContainer Bool (\ b => if b then Void else ())
我们的类型是通过获取容器的固定点获得的:
nat : Type
nat = W natC
我们可以恢复通常的构造函数:
zero : nat
zero = In (True ** \ v => absurd v)
succ : nat -> nat
succ n = In (False ** \ _ => n)
这是基于Abbott,Altenkirch和Ghani的“容器:构造严格的正类型”。