注入性

目录

介绍

如果F类是内射的,类型检查器知道F i=F j它可以得出结论i=j以解决进一步的约束。例如,如果F类是归纳族或构造函数的名称,它是内射的。如果F类则它通常不是内射的,但在某些重要情况下是内射的。例如,通过递归定义向量。

data Nat,其中零:自然例如:Nat->Nat数据为空,其中数据生产(A B:集合):集合,其中配对:A->B->产品A-BVec:(A:设置)->自然->设置Vec A零=空Vec A(成功)=产品A(Vec A n)

Vec公司是一个内射函数,可以通过在国家。我想在这种情况下,可以静态检查注入能力。如果能够指定函数是内射的(通过pragma),那就太好了,这样可以从类型检查器获得更多支持。

潜在问题

考虑以下方程组:

兽医A?0=血管A?1?1=成功归零

考虑到内射技巧,我们可以通过第一次实例化来求解这些方程?0 := ?1然后?1:=成功归零现在,假设我们试图以相反的顺序求解方程。我们最终会受到限制兽医A?0=生产A空我们不能只用内射技巧来解决这个问题。有两个选项:

  • 永远不要解决约束。例如,在应用注入性时,要求一侧是中性的。
  • 始终解决约束。这可能有点棘手。面对约束兽医A?0=生产A空我们必须弄清楚,这只可能发生在成功case和实例化?0:=成功?2.

更大的示例

这里有一个更大的例子,比较了一个类型的两种实现,一种是归纳,另一种是递归。

模块RecVsData,其中--空类型data Empty:设置位置--自然数data Nat:设置位置零:自然成功:Nat->Nat--向量data Vec(A:设置):自然->设置位置[]:Vec A Zero(向量A零点)_::_:对于所有{n}->A->Vec A n->Vec A(成功)infixr 20 _::_地图:{AB:集合}->(A->B)->所有{n}->Vec A n->Vec B n映射f[]=[]映射f(x::xs)=f x::映射f xs--大小类型,变量:i大小=自然--首次通过归纳数据类型进行编码模块KindData,其中数据类型:{_:Size}->设置位置mkKind:forall{in}->Vec(Kind{i})n->Kind{Succi}wkKind:forall{i}->Kind{i}->Kind{Succi}wkKind{成功i}(mkKind ks)=mkKint(映射wkKind-ks)--第二种编码,通过递归模块KindRec,其中数据MkKind(K:Set):设置位置mkKind:对于所有{n}->Vec K n->mkKind K种类:{_:大小}->设置种类{Zero}=空Kind{Succi}=MkKind(种类{i})wkKind:forall{i}->Kind{i}->Kind{Succi}wkKind{Zero}()wkKind{成功i}(mkKind ks)=mkKint(映射wkKind-ks)--三位未解决MVAR--已解决IF INSTEAD:mkKind(map(wkKind{i})ks)--用记录代替MkKind无法解决问题{-手动类型检查LHS ks=>Vec(种类{i})?1检查mkKind(映射wkKind ks)<=Kind{Succ(Succ i)}=MkKind(种类{Succi})检查映射wkKind ks<=Vec(Kind{Succi})?2推断地图=>所有{ABn}->(A->B)->Vec A n->Vec B n检查wkKind<=A->B推断wkKind?3=>种类{?3}->种类{成功?3}推断映射wkKind=>Vec(Kind{?3})?4->Vec(种类{Succ?3})?4检查ks<=Vec(种类{?3})?4解决?3=i由于Kind def.by.rec,可能未执行此设置。?4 = ?1推断映射wkKind ks=>Vec(Kind{Succ?3})?1解决?2 = ?1如果依赖Kind的*内射性*,那么设置?3=我可以成功!!-}
页面上次修改时间:2007年6月4日下午03时13分
技术支持私人维基