Haskell 秩2约束规划/约束蕴涵
使用Haskell 秩2约束规划/约束蕴涵,haskell,types,Haskell,Types,使用reify,我可以将约束c减弱为约束c',只要证明c'意味着c 现在,我想要这个的Rank2变体: import Data.Constraint reify :: (c' :- c) -> (c => a) -> (c' => a) reify cons f = case cons of Sub d -> case d of Dict -> f 但是我无法实现这样一个函数,即使它必须“清楚地”是可能的。使用ScopedTypeVariables+Typ
reify
,我可以将约束c
减弱为约束c'
,只要证明c'
意味着c
现在,我想要这个的Rank2
变体:
import Data.Constraint
reify :: (c' :- c) -> (c => a) -> (c' => a)
reify cons f = case cons of Sub d -> case d of Dict -> f
但是我无法实现这样一个函数,即使它必须“清楚地”是可能的。使用
ScopedTypeVariables+TypeApplications
可以消除歧义,尽管您需要对reify2
的参数重新排序,首先将类型参数放入范围
-- reify2 Rank2's reify
reify2 :: (forall r1. c' r1 :- c r1) ->
(forall r2. c r2 => a) ->
(forall r3. c' r3 => a)
reify2 cons f = ???
谢谢证明
reify2
与原始版本同构的证据是什么样的?我不是100%确信它们实现了相同的功能。在Haskell中很难做到这一点,因为有太多的歧义需要解决,而且我不确定如何实现原始签名。但例如,在Coq中,=>
是->
加上一些铃铛和口哨,->
反过来只是所有的糖,一个可以通过重新排序参数从另一个获得<代码>趣味c'a myreify2 cons f r3 Hc'r3=>myreify2 r3 c'a Hc'r3 cons f。
{-# LANGUAGE AllowAmbiguousTypes, RankNTypes, ConstraintKinds, GADTs, ScopedTypeVariables, TypeApplications, TypeOperators #-}
data Dict c where
Dict :: c => Dict c
data c :- d where
Sub :: (c => Dict d) -> c :- d
reify2 :: forall r3 c c' a. c' r3 =>
(forall r1. c' r1 :- c r1) ->
(forall r2. c r2 => a) ->
a
reify2 cons f =
case cons @r3 of
Sub Dict -> f @r3