Haskell GHC依赖类型编程的运行时代价
我正在用Haskell编写一个独立类型的库。在我的测试可执行文件上使用评测时,我看到如下情况:Haskell GHC依赖类型编程的运行时代价,haskell,optimization,runtime,compile-time,dependent-type,Haskell,Optimization,Runtime,Compile Time,Dependent Type,我正在用Haskell编写一个独立类型的库。在我的测试可执行文件上使用评测时,我看到如下情况: commutativity' Math 1189 4022787186 29.1 27.2 29.1 27.2 交换性“基本上是类型级整数的整数加法交换性属性的(递归)证明。定义如下: commutativity' :: SNat n -> SNat m -> Plus (S n) m :~: Plus n (S m) commutativity' SZ m = Refl commuta
commutativity' Math 1189 4022787186 29.1 27.2 29.1 27.2
交换性“
基本上是类型级整数的整数加法交换性属性的(递归)证明。定义如下:
commutativity' :: SNat n -> SNat m -> Plus (S n) m :~: Plus n (S m)
commutativity' SZ m = Refl
commutativity' (SS n) m = gcastWith (commutativity' n m) Refl
然后在我的库中使用gcastWith
来证明各种类型的等价性
所以。。。我29%的运行时都花在了一些完全无用的东西上,因为类型检查是在编译时进行的
我天真地认为这不会发生
我可以做些什么来优化这些无用的调用吗?如果您非常确定证明条件终止,您可以使用类似
unsafeProof :: proof -> proof
unsafeProof _ = unsafeCoerce ()
someFunction :: forall n m. ...
someFunction = case unsafeProof myProof :: Plus (S n) m :~: Plus n (S m) of
Refl -> ...
这只能用于具有单个无参数构造函数的类型,例如a:~:b
的Refl
。否则,您的程序可能会崩溃或行为异常。警告买主
一种更安全(但仍然不安全!)的变体可能是
unsafeProof :: a :~: b -> a :~: b
unsafeProof _ = unsafeCoerce ()
请注意,如果将底部传递给程序,您仍然可以使用该命令使程序崩溃
我希望有一天GHC能够安全自动地执行此优化,通过静态分析确保终止。这是不使用total语言的代价。类型安全性依赖于对规范形式的证明进行评估。在total语言中,证明无需评估即可信任,因此在运行时会被删除。一旦你检查了你的程序并通过了类型检查器,你就可以接受信任攻击并使用
非安全性检查
。参见Richard A.Eisenberg的论文《我梦想GHC集成终止(摘要)检查器》第4.4.4节“运行证明”,并使用零成本强制自动优化/重写“证明”。这真是太好了。“我认为部分递归是图灵完整性所必需的吗?”大多数程序都可以用非图灵完全语言编写。另外,根据你的想法,你可以在像Idris这样的语言中对部分函数进行建模:我的猜测是,这是因为这样的语言也有codata和生产性定义(即共归纳),这通常是不被考虑的,所以看起来终止+共归纳可能是图灵完全的(但不要引用我的话)。嗯。。。我猜在Richard Eisenberg实现依赖类型之后,对终止分析的需求将会更大。FWIW,我在base
和其他库()中经常看到的习惯用法是unsafeceorce Refl
,而不是unsafeceorce()
。我认为它对:~:
@BenjaminHodgson的表示形式的改变更具弹性,它更好地阐明了意图,是的。但是,对于一般情况,unsafeProof::proof->proof
没有我们可以使用的“最佳”构造函数,因此我使用了()
作为最终类型的规范元素。