等级2约束编程/约束含义

时间:2018-11-27 10:51:19

标签: haskell types

import Data.Constraint

reify :: (c' :- c) -> (c => a) -> (c' => a)
reify cons f = case cons of Sub d -> case d of Dict -> f

使用reify,我可以将约束c减弱为约束c',前提是证明c'暗示着c

现在,我想要一个Rank2的变体:

-- reify2 Rank2's reify
reify2 :: (forall r1. c' r1 :- c r1) -> 
          (forall r2. c r2 => a) -> 
          (forall r3. c' r3 => a)
reify2 cons f = ???

但是,即使必须“明显”可行,我也无法实现该功能。

1 个答案:

答案 0 :(得分:2)

可以使用ScopedTypeVariables+TypeApplications来消除歧义,尽管您需要重新排列reify2的参数,将类型参数放在范围内。

{-# 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