{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
module Data.Comp.Dict
( Dict (..)
, All
, withDict
, (\\)
, dictFor
) where
import GHC.Exts
import Data.Vector (Vector)
import qualified Data.Vector as V
import qualified Unsafe.Coerce as U
import Data.Comp.Elem
data E (f :: k1 -> *) where
E :: f e -> E f
data Dict (c :: k -> Constraint) (a :: k) where
Dict :: c a => Dict c a
withDict :: Dict c a -> (c a => r) -> r
withDict :: Dict c a -> (c a => r) -> r
withDict Dict x :: c a => r
x = r
c a => r
x
infixl 1 \\
(\\) :: (c a => r) -> Dict c a -> r
\\ :: (c a => r) -> Dict c a -> r
(\\) x :: c a => r
x Dict = r
c a => r
x
class All (c :: k -> Constraint) (fs :: [k]) where
dicts :: Proxy# fs -> [E (Dict c)]
instance All c '[] where
{-# INLINE dicts #-}
dicts :: Proxy# '[] -> [E (Dict c)]
dicts _ = []
instance (All c fs, c f) => All c (f ': fs) where
{-# INLINE dicts #-}
dicts :: Proxy# (f : fs) -> [E (Dict c)]
dicts p :: Proxy# (f : fs)
p = Dict c f -> E (Dict c)
forall k1 (f :: k1 -> *) (e :: k1). f e -> E f
E (Dict c f
forall k (c :: k -> Constraint) (a :: k). c a => Dict c a
Dict :: Dict c f) E (Dict c) -> [E (Dict c)] -> [E (Dict c)]
forall a. a -> [a] -> [a]
: (Proxy# fs -> [E (Dict c)]
forall k (c :: k -> Constraint) (fs :: [k]).
All c fs =>
Proxy# fs -> [E (Dict c)]
dicts (Proxy# (f : fs) -> Proxy# fs
forall k k (b :: k) (a :: k). Proxy# a -> Proxy# b
reproxy @fs Proxy# (f : fs)
p))
reproxy :: forall b a. Proxy# a -> Proxy# b
reproxy :: Proxy# a -> Proxy# b
reproxy _ = Proxy# b
forall k (a :: k). Proxy# a
proxy#
dictFor :: forall c f fs. (All c fs) => Elem f fs -> Dict c f
dictFor :: Elem f fs -> Dict c f
dictFor (Elem v :: Int
v) =
let ds :: Vector (E (Dict c))
ds = [E (Dict c)] -> Vector (E (Dict c))
forall a. [a] -> Vector a
V.fromList (Proxy# fs -> [E (Dict c)]
forall k (c :: k -> Constraint) (fs :: [k]).
All c fs =>
Proxy# fs -> [E (Dict c)]
dicts (Proxy# fs
forall k (a :: k). Proxy# a
proxy# :: Proxy# fs)) :: Vector (E (Dict c))
in case Vector (E (Dict c))
ds Vector (E (Dict c)) -> Int -> E (Dict c)
forall a. Vector a -> Int -> a
V.! Int
v of
E d :: Dict c e
d -> Dict c e -> Dict c f
forall a b. a -> b
U.unsafeCoerce Dict c e
d
{-# INLINE dictFor #-}