module Data.Parameterized.Context.Unsafe
( module Data.Parameterized.Ctx
, Size
, sizeInt
, zeroSize
, incSize
, decSize
, extSize
, addSize
, SizeView(..)
, viewSize
, KnownContext(..)
, Diff
, noDiff
, extendRight
, KnownDiff(..)
, DiffView(..)
, viewDiff
, Index
, indexVal
, base
, skip
, lastIndex
, nextIndex
, extendIndex
, extendIndex'
, forIndex
, forIndexRange
, forIndexM
, intIndex
, IndexRange
, allRange
, indexOfRange
, dropHeadRange
, dropTailRange
, Assignment
, size
, replicate
, generate
, generateM
, generateSome
, generateSomeM
, empty
, null
, extend
, update
, adjust
, adjustM
, init
, last
, AssignView(..)
, view
, decompose
, fromList
, (!)
, (!^)
, zipWith
, zipWithM
, (<++>)
, traverseWithIndex
) where
import Control.Applicative hiding (empty)
import qualified Control.Category as Cat
import Control.DeepSeq
import Control.Exception
import qualified Control.Lens as Lens
import Control.Monad.Identity (Identity(..))
import Data.Bits
import Data.Coerce
import Data.Hashable
import Data.List (intercalate)
import Data.Proxy
import Unsafe.Coerce
import Prelude hiding (init, last, map, null, replicate, succ, zipWith, (++))
import qualified Prelude
import Data.Parameterized.Classes
import Data.Parameterized.Ctx
import Data.Parameterized.Ctx.Proofs
import Data.Parameterized.Some
import Data.Parameterized.TraversableFC
newtype Size (ctx :: Ctx k) = Size { sizeInt :: Int }
zeroSize :: Size 'EmptyCtx
zeroSize = Size 0
incSize :: Size ctx -> Size (ctx '::> tp)
incSize (Size n) = Size (n+1)
decSize :: Size (ctx '::> tp) -> Size ctx
decSize (Size n) = assert (n > 0) (Size (n1))
data SizeView (ctx :: Ctx k) where
ZeroSize :: SizeView 'EmptyCtx
IncSize :: !(Size ctx) -> SizeView (ctx '::> tp)
viewSize :: Size ctx -> SizeView ctx
viewSize (Size 0) = unsafeCoerce ZeroSize
viewSize (Size n) = assert (n > 0) (unsafeCoerce (IncSize (Size (n1))))
instance Show (Size ctx) where
show (Size i) = show i
class KnownContext (ctx :: Ctx k) where
knownSize :: Size ctx
instance KnownContext 'EmptyCtx where
knownSize = zeroSize
instance KnownContext ctx => KnownContext (ctx '::> tp) where
knownSize = incSize knownSize
newtype Diff (l :: Ctx k) (r :: Ctx k)
= Diff { _contextExtSize :: Int }
noDiff :: Diff l l
noDiff = Diff 0
extendRight :: Diff l r -> Diff l (r '::> tp)
extendRight (Diff i) = Diff (i+1)
instance Cat.Category Diff where
id = Diff 0
Diff j . Diff i = Diff (i + j)
extSize :: Size l -> Diff l r -> Size r
extSize (Size i) (Diff j) = Size (i+j)
addSize :: Size x -> Size y -> Size (x <+> y)
addSize (Size x) (Size y) = Size (x + y)
data DiffView a b where
NoDiff :: DiffView a a
ExtendRightDiff :: Diff a b -> DiffView a (b ::> r)
viewDiff :: Diff a b -> DiffView a b
viewDiff (Diff i)
| i == 0 = unsafeCoerce NoDiff
| otherwise = assert (i > 0) $ unsafeCoerce $ ExtendRightDiff (Diff (i1))
class KnownDiff (l :: Ctx k) (r :: Ctx k) where
knownDiff :: Diff l r
instance KnownDiff l l where
knownDiff = noDiff
instance KnownDiff l r => KnownDiff l (r '::> tp) where
knownDiff = extendRight knownDiff
newtype Index (ctx :: Ctx k) (tp :: k) = Index { indexVal :: Int }
instance Eq (Index ctx tp) where
Index i == Index j = i == j
instance TestEquality (Index ctx) where
testEquality (Index i) (Index j)
| i == j = Just (unsafeCoerce Refl)
| otherwise = Nothing
instance Ord (Index ctx tp) where
Index i `compare` Index j = compare i j
instance OrdF (Index ctx) where
compareF (Index i) (Index j)
| i < j = LTF
| i == j = unsafeCoerce EQF
| otherwise = GTF
base :: Index ('EmptyCtx '::> tp) tp
base = Index 0
skip :: Index ctx x -> Index (ctx '::> y) x
skip (Index i) = Index i
nextIndex :: Size ctx -> Index (ctx ::> tp) tp
nextIndex n = Index (sizeInt n)
lastIndex :: Size (ctx ::> tp) -> Index (ctx ::> tp) tp
lastIndex n = Index (sizeInt n 1)
extendIndex :: KnownDiff l r => Index l tp -> Index r tp
extendIndex = extendIndex' knownDiff
extendIndex' :: Diff l r -> Index l tp -> Index r tp
extendIndex' _ = unsafeCoerce
forIndex :: forall ctx r
. Size ctx
-> (forall tp . r -> Index ctx tp -> r)
-> r
-> r
forIndex n f r =
case viewSize n of
ZeroSize -> r
IncSize p -> f (forIndex p (coerce f) r) (nextIndex p)
forIndexRange :: forall ctx r
. Int
-> Size ctx
-> (forall tp . Index ctx tp -> r -> r)
-> r
-> r
forIndexRange i (Size n) f r
| i >= n = r
| otherwise = f (Index i) (forIndexRange (i+1) (Size n) f r)
forIndexM :: forall ctx m
. Applicative m
=> Size ctx
-> (forall tp . Index ctx tp -> m ())
-> m ()
forIndexM sz f = forIndexRange 0 sz (\i r -> f i *> r) (pure ())
intIndex :: Int -> Size ctx -> Maybe (Some (Index ctx))
intIndex i n | 0 <= i && i < sizeInt n = Just (Some (Index i))
| otherwise = Nothing
instance Show (Index ctx tp) where
show = show . indexVal
instance ShowF (Index ctx)
data IndexRange (ctx :: Ctx k) (sub :: Ctx k)
= IndexRange !Int
!Int
allRange :: Size ctx -> IndexRange ctx ctx
allRange (Size n) = IndexRange 0 n
indexOfRange :: IndexRange ctx (EmptyCtx ::> e) -> Index ctx e
indexOfRange (IndexRange i n) = assert (n == 1) $ Index i
dropTailRange :: IndexRange ctx (x <+> y) -> Size y -> IndexRange ctx x
dropTailRange (IndexRange i n) (Size j) = assert (n >= j) $ IndexRange i (n j)
dropHeadRange :: IndexRange ctx (x <+> y) -> Size x -> IndexRange ctx y
dropHeadRange (IndexRange i n) (Size j) = assert (i' >= i && n >= j) $ IndexRange i' (n j)
where i' = i + j
data Height = Zero | Succ Height
type family Pred (k :: Height) :: Height
type instance Pred ('Succ h) = h
data BalancedTree h (f :: k -> *) (p :: Ctx k) where
BalLeaf :: !(f x) -> BalancedTree 'Zero f (SingleCtx x)
BalPair :: !(BalancedTree h f x)
-> !(BalancedTree h f y)
-> BalancedTree ('Succ h) f (x <+> y)
bal_size :: BalancedTree h f p -> Int
bal_size (BalLeaf _) = 1
bal_size (BalPair x y) = bal_size x + bal_size y
instance TestEqualityFC (BalancedTree h) where
testEqualityFC test (BalLeaf x) (BalLeaf y) = do
Refl <- test x y
return Refl
testEqualityFC test (BalPair x1 x2) (BalPair y1 y2) = do
Refl <- testEqualityFC test x1 y1
Refl <- testEqualityFC test x2 y2
return Refl
#if !MIN_VERSION_base(4,9,0)
testEqualityFC _ _ _ = Nothing
#endif
instance OrdFC (BalancedTree h) where
compareFC test (BalLeaf x) (BalLeaf y) =
joinOrderingF (test x y) $ EQF
#if !MIN_VERSION_base(4,9,0)
compareFC _ BalLeaf{} _ = LTF
compareFC _ _ BalLeaf{} = GTF
#endif
compareFC test (BalPair x1 x2) (BalPair y1 y2) =
joinOrderingF (compareFC test x1 y1) $
joinOrderingF (compareFC test x2 y2) $
EQF
instance HashableF f => HashableF (BalancedTree h f) where
hashWithSaltF s t =
case t of
BalLeaf x -> s `hashWithSaltF` x
BalPair x y -> s `hashWithSaltF` x `hashWithSaltF` y
fmap_bal :: (forall tp . f tp -> g tp)
-> BalancedTree h f c
-> BalancedTree h g c
fmap_bal = go
where go :: (forall tp . f tp -> g tp)
-> BalancedTree h f c
-> BalancedTree h g c
go f (BalLeaf x) = BalLeaf (f x)
go f (BalPair x y) = BalPair (go f x) (go f y)
traverse_bal :: Applicative m
=> (forall tp . f tp -> m (g tp))
-> BalancedTree h f c
-> m (BalancedTree h g c)
traverse_bal = go
where go :: Applicative m
=> (forall tp . f tp -> m (g tp))
-> BalancedTree h f c
-> m (BalancedTree h g c)
go f (BalLeaf x) = BalLeaf <$> f x
go f (BalPair x y) = BalPair <$> go f x <*> go f y
instance ShowF f => Show (BalancedTree h f tp) where
show (BalLeaf x) = showF x
show (BalPair x y) = "BalPair " Prelude.++ show x Prelude.++ " " Prelude.++ show y
instance ShowF f => ShowF (BalancedTree h f)
unsafe_bal_generate :: forall ctx h f t
. Int
-> Int
-> (forall tp . Index ctx tp -> f tp)
-> BalancedTree h f t
unsafe_bal_generate h o f
| h < 0 = error "unsafe_bal_generate given negative height"
| h == 0 = unsafeCoerce $ BalLeaf (f (Index o))
| otherwise =
let l = unsafe_bal_generate (h1) o f
o' = o + 1 `shiftL` (h1)
u = assert (o + bal_size l == o') $ unsafe_bal_generate (h1) o' f
in unsafeCoerce $ BalPair l u
unsafe_bal_generateM :: forall m ctx h f t
. Applicative m
=> Int
-> Int
-> (forall x . Index ctx x -> m (f x))
-> m (BalancedTree h f t)
unsafe_bal_generateM h o f
| h == 0 = unsafeCoerce . BalLeaf <$> f (Index o)
| otherwise =
let o' = o + 1 `shiftL` (h1)
g lv uv = assert (o' == o + bal_size lv) $
unsafeCoerce (BalPair lv uv)
in g <$> unsafe_bal_generateM (h1) o f
<*> unsafe_bal_generateM (h1) o' f
unsafe_bal_index :: BalancedTree h f a
-> Int
-> Int
-> f tp
unsafe_bal_index _ j i
| seq j $ seq i $ False = error "bad unsafe_bal_index"
unsafe_bal_index (BalLeaf u) _ i = assert (i == 0) $ unsafeCoerce u
unsafe_bal_index (BalPair x y) j i
| j `testBit` (i1) = unsafe_bal_index y j $! (i1)
| otherwise = unsafe_bal_index x j $! (i1)
unsafe_bal_adjust :: Functor m
=> (f x -> m (f y))
-> BalancedTree h f a
-> Int
-> Int
-> m (BalancedTree h f b)
unsafe_bal_adjust f (BalLeaf u) _ i = assert (i == 0) $
(unsafeCoerce . BalLeaf <$> (f (unsafeCoerce u)))
unsafe_bal_adjust f (BalPair x y) j i
| j `testBit` (i1) = (unsafeCoerce . BalPair x <$> (unsafe_bal_adjust f y j (i1)))
| otherwise = (unsafeCoerce . flip BalPair y <$> (unsafe_bal_adjust f x j (i1)))
bal_zipWithM :: Applicative m
=> (forall x . f x -> g x -> m (h x))
-> BalancedTree u f a
-> BalancedTree u g a
-> m (BalancedTree u h a)
bal_zipWithM f (BalLeaf x) (BalLeaf y) = BalLeaf <$> f x y
bal_zipWithM f (BalPair x1 x2) (BalPair y1 y2) =
BalPair <$> bal_zipWithM f x1 (unsafeCoerce y1)
<*> bal_zipWithM f x2 (unsafeCoerce y2)
#if !MIN_VERSION_base(4,9,0)
bal_zipWithM _ _ _ = error "ilegal args to bal_zipWithM"
#endif
data BinomialTree (h::Height) (f :: k -> *) :: Ctx k -> * where
Empty :: BinomialTree h f EmptyCtx
PlusOne :: !Int
-> !(BinomialTree ('Succ h) f x)
-> !(BalancedTree h f y)
-> BinomialTree h f (x <+> y)
PlusZero :: !Int
-> !(BinomialTree ('Succ h) f x)
-> BinomialTree h f x
tsize :: BinomialTree h f a -> Int
tsize Empty = 0
tsize (PlusOne s _ _) = 2*s+1
tsize (PlusZero s _) = 2*s
t_cnt_size :: BinomialTree h f a -> Int
t_cnt_size Empty = 0
t_cnt_size (PlusOne _ l r) = t_cnt_size l + bal_size r
t_cnt_size (PlusZero _ l) = t_cnt_size l
append :: BinomialTree h f x
-> BalancedTree h f y
-> BinomialTree h f (x <+> y)
append Empty y = PlusOne 0 Empty y
append (PlusOne _ t x) y =
case assoc t x y of
Refl ->
let t' = append t (BalPair x y)
in PlusZero (tsize t') t'
append (PlusZero s t) x = PlusOne s t x
instance TestEqualityFC (BinomialTree h) where
testEqualityFC _ Empty Empty = return Refl
testEqualityFC test (PlusZero _ x1) (PlusZero _ y1) = do
Refl <- testEqualityFC test x1 y1
return Refl
testEqualityFC test (PlusOne _ x1 x2) (PlusOne _ y1 y2) = do
Refl <- testEqualityFC test x1 y1
Refl <- testEqualityFC test x2 y2
return Refl
testEqualityFC _ _ _ = Nothing
instance OrdFC (BinomialTree h) where
compareFC _ Empty Empty = EQF
compareFC _ Empty _ = LTF
compareFC _ _ Empty = GTF
compareFC test (PlusZero _ x1) (PlusZero _ y1) =
joinOrderingF (compareFC test x1 y1) $ EQF
compareFC _ PlusZero{} _ = LTF
compareFC _ _ PlusZero{} = GTF
compareFC test (PlusOne _ x1 x2) (PlusOne _ y1 y2) =
joinOrderingF (compareFC test x1 y1) $
joinOrderingF (compareFC test x2 y2) $
EQF
instance HashableF f => HashableF (BinomialTree h f) where
hashWithSaltF s t =
case t of
Empty -> s
PlusZero _ x -> s `hashWithSaltF` x
PlusOne _ x y -> s `hashWithSaltF` x `hashWithSaltF` y
fmap_bin :: (forall tp . f tp -> g tp)
-> BinomialTree h f c
-> BinomialTree h g c
fmap_bin _ Empty = Empty
fmap_bin f (PlusOne s t x) = PlusOne s (fmap_bin f t) (fmap_bal f x)
fmap_bin f (PlusZero s t) = PlusZero s (fmap_bin f t)
traverse_bin :: Applicative m
=> (forall tp . f tp -> m (g tp))
-> BinomialTree h f c
-> m (BinomialTree h g c)
traverse_bin _ Empty = pure Empty
traverse_bin f (PlusOne s t x) = PlusOne s <$> traverse_bin f t <*> traverse_bal f x
traverse_bin f (PlusZero s t) = PlusZero s <$> traverse_bin f t
unsafe_bin_generate :: forall h f ctx t
. Int
-> Int
-> (forall x . Index ctx x -> f x)
-> BinomialTree h f t
unsafe_bin_generate sz h f
| sz == 0 = unsafeCoerce Empty
| sz `testBit` 0 =
let s = sz `shiftR` 1
t = unsafe_bin_generate s (h+1) f
o = s * 2^(h+1)
u = assert (o == t_cnt_size t) $ unsafe_bal_generate h o f
in unsafeCoerce (PlusOne s t u)
| otherwise =
let s = sz `shiftR` 1
t = unsafe_bin_generate (sz `shiftR` 1) (h+1) f
r :: BinomialTree h f t
r = PlusZero s t
in r
unsafe_bin_generateM :: forall m h f ctx t
. Applicative m
=> Int
-> Int
-> (forall x . Index ctx x -> m (f x))
-> m (BinomialTree h f t)
unsafe_bin_generateM sz h f
| sz == 0 = pure (unsafeCoerce Empty)
| sz `testBit` 0 =
let s = sz `shiftR` 1
t = unsafe_bin_generateM s (h+1) f
o = s * 2^(h+1)
u = unsafe_bal_generateM h o f
r = unsafeCoerce (PlusOne s) <$> t <*> u
in r
| otherwise =
let s = sz `shiftR` 1
t = unsafe_bin_generateM s (h+1) f
r :: m (BinomialTree h f t)
r = PlusZero s <$> t
in r
type family InitCtx (x :: Ctx k) :: Ctx k
type instance InitCtx (x ::> y) = x
type family LastCtx (x :: Ctx k) :: k
type instance LastCtx (x ::> y) = y
data DropResult f (ctx :: Ctx k) where
DropEmpty :: DropResult f EmptyCtx
DropExt :: BinomialTree 'Zero f (InitCtx ctx)
-> f (LastCtx ctx)
-> DropResult f ctx
bal_drop :: forall h f x y
. BinomialTree h f x
-> BalancedTree h f y
-> DropResult f (x <+> y)
bal_drop t (BalLeaf e) = DropExt t e
bal_drop t (BalPair x y) =
unsafeCoerce (bal_drop (PlusOne (tsize t) (unsafeCoerce t) x) y)
bin_drop :: forall h f ctx
. BinomialTree h f ctx
-> DropResult f ctx
bin_drop Empty = DropEmpty
bin_drop (PlusZero _ u) = bin_drop u
bin_drop (PlusOne s t u) =
let m = case t of
Empty -> Empty
_ -> PlusZero s t
in bal_drop m u
unsafe_bin_index :: BinomialTree h f a
-> Int
-> Int
-> f u
unsafe_bin_index _ _ i
| seq i False = error "bad unsafe_bin_index"
unsafe_bin_index Empty _ _ = error "unsafe_bin_index reached end of list"
unsafe_bin_index (PlusOne sz t u) j i
| sz == j `shiftR` (1+i) = unsafe_bal_index u j i
| otherwise = unsafe_bin_index t j $! (1+i)
unsafe_bin_index (PlusZero sz t) j i
| sz == j `shiftR` (1+i) = error "unsafe_bin_index stopped at PlusZero"
| otherwise = unsafe_bin_index t j $! (1+i)
unsafe_bin_adjust :: forall m h f x y a b
. Functor m
=> (f x -> m (f y))
-> BinomialTree h f a
-> Int
-> Int
-> m (BinomialTree h f b)
unsafe_bin_adjust _ Empty _ _ = error "unsafe_bin_adjust reached end of list"
unsafe_bin_adjust f (PlusOne sz t u) j i
| sz == j `shiftR` (1+i) =
unsafeCoerce . PlusOne sz t <$> (unsafe_bal_adjust f u j i)
| otherwise =
unsafeCoerce . flip (PlusOne sz) u <$> (unsafe_bin_adjust f t j (i+1))
unsafe_bin_adjust f (PlusZero sz t) j i
| sz == j `shiftR` (1+i) = error "unsafe_bin_adjust stopped at PlusZero"
| otherwise = PlusZero sz <$> (unsafe_bin_adjust f t j (i+1))
tree_zipWithM :: Applicative m
=> (forall x . f x -> g x -> m (h x))
-> BinomialTree u f a
-> BinomialTree u g a
-> m (BinomialTree u h a)
tree_zipWithM _ Empty Empty = pure Empty
tree_zipWithM f (PlusOne s x1 x2) (PlusOne _ y1 y2) =
PlusOne s <$> tree_zipWithM f x1 (unsafeCoerce y1)
<*> bal_zipWithM f x2 (unsafeCoerce y2)
tree_zipWithM f (PlusZero s x1) (PlusZero _ y1) =
PlusZero s <$> tree_zipWithM f x1 y1
tree_zipWithM _ _ _ = error "ilegal args to tree_zipWithM"
type role Assignment representational nominal
newtype Assignment (f :: k -> *) (ctx :: Ctx k)
= Assignment (BinomialTree 'Zero f ctx)
instance NFData (Assignment f ctx) where
rnf a = seq a ()
size :: Assignment f ctx -> Size ctx
size (Assignment t) = Size (tsize t)
generateSome :: forall f
. Int
-> (Int -> Some f)
-> Some (Assignment f)
generateSome n f = go n
where go :: Int -> Some (Assignment f)
go 0 = Some empty
go i = (\(Some a) (Some e) -> Some (a `extend` e)) (go (i1)) (f (i1))
generateSomeM :: forall m f
. Applicative m
=> Int
-> (Int -> m (Some f))
-> m (Some (Assignment f))
generateSomeM n f = go n
where go :: Int -> m (Some (Assignment f))
go 0 = pure (Some empty)
go i = (\(Some a) (Some e) -> Some (a `extend` e)) <$> go (i1) <*> f (i1)
replicate :: Size ctx -> (forall tp . f tp) -> Assignment f ctx
replicate n c = generate n (\_ -> c)
generate :: Size ctx
-> (forall tp . Index ctx tp -> f tp)
-> Assignment f ctx
generate n f = Assignment r
where r = unsafe_bin_generate (sizeInt n) 0 f
generateM :: Applicative m
=> Size ctx
-> (forall tp . Index ctx tp -> m (f tp))
-> m (Assignment f ctx)
generateM n f = Assignment <$> unsafe_bin_generateM (sizeInt n) 0 f
empty :: Assignment f EmptyCtx
empty = Assignment Empty
null :: Assignment f ctx -> Bool
null (Assignment Empty) = True
null (Assignment _) = False
extend :: Assignment f ctx -> f x -> Assignment f (ctx ::> x)
extend (Assignment x) y = Assignment $ append x (BalLeaf y)
unsafeIndex :: proxy u -> Int -> Assignment f ctx -> f u
unsafeIndex _ idx (Assignment t) = seq t $ unsafe_bin_index t idx 0
(!) :: Assignment f ctx -> Index ctx tp -> f tp
a ! Index i = assert (0 <= i && i < sizeInt (size a)) $
unsafeIndex Proxy i a
(!^) :: KnownDiff l r => Assignment f r -> Index l tp -> f tp
a !^ i = a ! extendIndex i
instance TestEqualityFC Assignment where
testEqualityFC test (Assignment x) (Assignment y) = do
Refl <- testEqualityFC test x y
return Refl
instance TestEquality f => TestEquality (Assignment f) where
testEquality = testEqualityFC testEquality
instance TestEquality f => Eq (Assignment f ctx) where
x == y = isJust (testEquality x y)
instance OrdFC Assignment where
compareFC test (Assignment x) (Assignment y) =
joinOrderingF (compareFC test x y) $ EQF
instance OrdF f => OrdF (Assignment f) where
compareF = compareFC compareF
instance OrdF f => Ord (Assignment f ctx) where
compare x y = toOrdering (compareF x y)
instance HashableF (Index ctx) where
hashWithSaltF s i = hashWithSalt s (indexVal i)
instance Hashable (Index ctx tp) where
hashWithSalt = hashWithSaltF
instance HashableF f => Hashable (Assignment f ctx) where
hashWithSalt s (Assignment a) = hashWithSaltF s a
instance HashableF f => HashableF (Assignment f) where
hashWithSaltF = hashWithSalt
instance ShowF f => Show (Assignment f ctx) where
show a = "[" Prelude.++ intercalate ", " (toListFC showF a) Prelude.++ "]"
instance ShowF f => ShowF (Assignment f)
adjustM :: Functor m => (f tp -> m (f tp)) -> Index ctx tp -> Assignment f ctx -> m (Assignment f ctx)
adjustM f (Index i) (Assignment a) = Assignment <$> (unsafe_bin_adjust f a i 0)
type instance IndexF (Assignment f ctx) = Index ctx
type instance IxValueF (Assignment f ctx) = f
instance forall (f :: k -> *) ctx. IxedF k (Assignment f ctx) where
ixF :: Index ctx x -> Lens.Lens' (Assignment f ctx) (f x)
ixF idx f = adjustM f idx
instance forall (f :: k -> *) ctx. IxedF' k (Assignment f ctx) where
ixF' :: Index ctx x -> Lens.Lens' (Assignment f ctx) (f x)
ixF' idx f = adjustM f idx
adjust :: (f tp -> f tp) -> Index ctx tp -> Assignment f ctx -> Assignment f ctx
adjust f idx asgn = runIdentity (adjustM (Identity . f) idx asgn)
update :: Index ctx tp -> f tp -> Assignment f ctx -> Assignment f ctx
update i v a = adjust (\_ -> v) i a
unsafeUpdate :: Int -> Assignment f ctx -> f u -> Assignment f ctx'
unsafeUpdate i (Assignment a) e = Assignment (runIdentity (unsafe_bin_adjust (\_ -> Identity e) a i 0))
data AssignView f ctx where
AssignEmpty :: AssignView f EmptyCtx
AssignExtend :: Assignment f ctx
-> f tp
-> AssignView f (ctx::>tp)
view :: forall f ctx . Assignment f ctx -> AssignView f ctx
view (Assignment x) =
case bin_drop x of
DropEmpty -> AssignEmpty
DropExt t v -> unsafeCoerce $ AssignExtend (Assignment (unsafeCoerce t)) v
init :: Assignment f (ctx '::> tp) -> Assignment f ctx
init (Assignment x) =
case bin_drop x of
DropExt t _ -> Assignment t
last :: Assignment f (ctx '::> tp) -> f tp
last x =
case view x of
AssignExtend _ e -> e
decompose :: Assignment f (ctx ::> tp) -> (Assignment f ctx, f tp)
decompose x = case view x of AssignExtend a v -> (a,v)
zipWith :: (forall x . f x -> g x -> h x)
-> Assignment f a
-> Assignment g a
-> Assignment h a
zipWith f = \x y -> runIdentity $ zipWithM (\u v -> pure (f u v)) x y
zipWithM :: Applicative m
=> (forall x . f x -> g x -> m (h x))
-> Assignment f a
-> Assignment g a
-> m (Assignment h a)
zipWithM f (Assignment x) (Assignment y) = Assignment <$> tree_zipWithM f x y
instance FunctorFC Assignment where
fmapFC = \f (Assignment x) -> Assignment (fmap_bin f x)
instance FoldableFC Assignment where
foldMapFC = foldMapFCDefault
instance TraversableFC Assignment where
traverseFC = \f (Assignment x) -> Assignment <$> traverse_bin f x
traverseWithIndex :: Applicative m
=> (forall tp . Index ctx tp -> f tp -> m (g tp))
-> Assignment f ctx
-> m (Assignment g ctx)
traverseWithIndex f a = generateM (size a) $ \i -> f i (a ! i)
fromList :: [Some f] -> Some (Assignment f)
fromList = go empty
where go :: Assignment f ctx -> [Some f] -> Some (Assignment f)
go prev [] = Some prev
go prev (Some g:next) = (go $! prev `extend` g) next
appendBal :: Assignment f x -> BalancedTree h f y -> Assignment f (x <+> y)
appendBal x (BalLeaf a) = x `extend` a
appendBal x (BalPair y z) =
case assoc x y z of
Refl -> x `appendBal` y `appendBal` z
appendBin :: Assignment f x -> BinomialTree h f y -> Assignment f (x <+> y)
appendBin x Empty = x
appendBin x (PlusOne _ y z) =
case assoc x y z of
Refl -> x `appendBin` y `appendBal` z
appendBin x (PlusZero _ y) = x `appendBin` y
(<++>) :: Assignment f x -> Assignment f y -> Assignment f (x <+> y)
x <++> Assignment y = x `appendBin` y
instance (KnownRepr (Assignment f) ctx, KnownRepr f bt)
=> KnownRepr (Assignment f) (ctx ::> bt) where
knownRepr = knownRepr `extend` knownRepr
instance KnownRepr (Assignment f) EmptyCtx where
knownRepr = empty
unsafeLens :: Int -> Lens.Lens (Assignment f ctx) (Assignment f ctx') (f tp) (f u)
unsafeLens idx =
Lens.lens (unsafeIndex Proxy idx) (unsafeUpdate idx)
type Assignment1 f x1 = Assignment f ('EmptyCtx '::> x1)
instance Lens.Field1 (Assignment1 f t) (Assignment1 f u) (f t) (f u) where
_1 = unsafeLens 0
type Assignment2 f x1 x2
= Assignment f ('EmptyCtx '::> x1 '::> x2)
instance Lens.Field1 (Assignment2 f t x2) (Assignment2 f u x2) (f t) (f u) where
_1 = unsafeLens 0
instance Lens.Field2 (Assignment2 f x1 t) (Assignment2 f x1 u) (f t) (f u) where
_2 = unsafeLens 1
type Assignment3 f x1 x2 x3
= Assignment f ('EmptyCtx '::> x1 '::> x2 '::> x3)
instance Lens.Field1 (Assignment3 f t x2 x3)
(Assignment3 f u x2 x3)
(f t)
(f u) where
_1 = unsafeLens 0
instance Lens.Field2 (Assignment3 f x1 t x3)
(Assignment3 f x1 u x3)
(f t)
(f u) where
_2 = unsafeLens 1
instance Lens.Field3 (Assignment3 f x1 x2 t)
(Assignment3 f x1 x2 u)
(f t)
(f u) where
_3 = unsafeLens 2
type Assignment4 f x1 x2 x3 x4
= Assignment f ('EmptyCtx '::> x1 '::> x2 '::> x3 '::> x4)
instance Lens.Field1 (Assignment4 f t x2 x3 x4)
(Assignment4 f u x2 x3 x4)
(f t)
(f u) where
_1 = unsafeLens 0
instance Lens.Field2 (Assignment4 f x1 t x3 x4)
(Assignment4 f x1 u x3 x4)
(f t)
(f u) where
_2 = unsafeLens 1
instance Lens.Field3 (Assignment4 f x1 x2 t x4)
(Assignment4 f x1 x2 u x4)
(f t)
(f u) where
_3 = unsafeLens 2
instance Lens.Field4 (Assignment4 f x1 x2 x3 t)
(Assignment4 f x1 x2 x3 u)
(f t)
(f u) where
_4 = unsafeLens 3
type Assignment5 f x1 x2 x3 x4 x5
= Assignment f ('EmptyCtx '::> x1 '::> x2 '::> x3 '::> x4 '::> x5)
instance Lens.Field1 (Assignment5 f t x2 x3 x4 x5)
(Assignment5 f u x2 x3 x4 x5)
(f t)
(f u) where
_1 = unsafeLens 0
instance Lens.Field2 (Assignment5 f x1 t x3 x4 x5)
(Assignment5 f x1 u x3 x4 x5)
(f t)
(f u) where
_2 = unsafeLens 1
instance Lens.Field3 (Assignment5 f x1 x2 t x4 x5)
(Assignment5 f x1 x2 u x4 x5)
(f t)
(f u) where
_3 = unsafeLens 2
instance Lens.Field4 (Assignment5 f x1 x2 x3 t x5)
(Assignment5 f x1 x2 x3 u x5)
(f t)
(f u) where
_4 = unsafeLens 3
instance Lens.Field5 (Assignment5 f x1 x2 x3 x4 t)
(Assignment5 f x1 x2 x3 x4 u)
(f t)
(f u) where
_5 = unsafeLens 4
type Assignment6 f x1 x2 x3 x4 x5 x6
= Assignment f ('EmptyCtx '::> x1 '::> x2 '::> x3 '::> x4 '::> x5 '::> x6)
instance Lens.Field1 (Assignment6 f t x2 x3 x4 x5 x6)
(Assignment6 f u x2 x3 x4 x5 x6)
(f t)
(f u) where
_1 = unsafeLens 0
instance Lens.Field2 (Assignment6 f x1 t x3 x4 x5 x6)
(Assignment6 f x1 u x3 x4 x5 x6)
(f t)
(f u) where
_2 = unsafeLens 1
instance Lens.Field3 (Assignment6 f x1 x2 t x4 x5 x6)
(Assignment6 f x1 x2 u x4 x5 x6)
(f t)
(f u) where
_3 = unsafeLens 2
instance Lens.Field4 (Assignment6 f x1 x2 x3 t x5 x6)
(Assignment6 f x1 x2 x3 u x5 x6)
(f t)
(f u) where
_4 = unsafeLens 3
instance Lens.Field5 (Assignment6 f x1 x2 x3 x4 t x6)
(Assignment6 f x1 x2 x3 x4 u x6)
(f t)
(f u) where
_5 = unsafeLens 4
instance Lens.Field6 (Assignment6 f x1 x2 x3 x4 x5 t)
(Assignment6 f x1 x2 x3 x4 x5 u)
(f t)
(f u) where
_6 = unsafeLens 5
type Assignment7 f x1 x2 x3 x4 x5 x6 x7
= Assignment f ('EmptyCtx '::> x1 '::> x2 '::> x3 '::> x4 '::> x5 '::> x6 '::> x7)
instance Lens.Field1 (Assignment7 f t x2 x3 x4 x5 x6 x7)
(Assignment7 f u x2 x3 x4 x5 x6 x7)
(f t)
(f u) where
_1 = unsafeLens 0
instance Lens.Field2 (Assignment7 f x1 t x3 x4 x5 x6 x7)
(Assignment7 f x1 u x3 x4 x5 x6 x7)
(f t)
(f u) where
_2 = unsafeLens 1
instance Lens.Field3 (Assignment7 f x1 x2 t x4 x5 x6 x7)
(Assignment7 f x1 x2 u x4 x5 x6 x7)
(f t)
(f u) where
_3 = unsafeLens 2
instance Lens.Field4 (Assignment7 f x1 x2 x3 t x5 x6 x7)
(Assignment7 f x1 x2 x3 u x5 x6 x7)
(f t)
(f u) where
_4 = unsafeLens 3
instance Lens.Field5 (Assignment7 f x1 x2 x3 x4 t x6 x7)
(Assignment7 f x1 x2 x3 x4 u x6 x7)
(f t)
(f u) where
_5 = unsafeLens 4
instance Lens.Field6 (Assignment7 f x1 x2 x3 x4 x5 t x7)
(Assignment7 f x1 x2 x3 x4 x5 u x7)
(f t)
(f u) where
_6 = unsafeLens 5
instance Lens.Field7 (Assignment7 f x1 x2 x3 x4 x5 x6 t)
(Assignment7 f x1 x2 x3 x4 x5 x6 u)
(f t)
(f u) where
_7 = unsafeLens 6
type Assignment8 f x1 x2 x3 x4 x5 x6 x7 x8
= Assignment f ('EmptyCtx '::> x1 '::> x2 '::> x3 '::> x4 '::> x5 '::> x6 '::> x7 '::> x8)
instance Lens.Field1 (Assignment8 f t x2 x3 x4 x5 x6 x7 x8)
(Assignment8 f u x2 x3 x4 x5 x6 x7 x8)
(f t)
(f u) where
_1 = unsafeLens 0
instance Lens.Field2 (Assignment8 f x1 t x3 x4 x5 x6 x7 x8)
(Assignment8 f x1 u x3 x4 x5 x6 x7 x8)
(f t)
(f u) where
_2 = unsafeLens 1
instance Lens.Field3 (Assignment8 f x1 x2 t x4 x5 x6 x7 x8)
(Assignment8 f x1 x2 u x4 x5 x6 x7 x8)
(f t)
(f u) where
_3 = unsafeLens 2
instance Lens.Field4 (Assignment8 f x1 x2 x3 t x5 x6 x7 x8)
(Assignment8 f x1 x2 x3 u x5 x6 x7 x8)
(f t)
(f u) where
_4 = unsafeLens 3
instance Lens.Field5 (Assignment8 f x1 x2 x3 x4 t x6 x7 x8)
(Assignment8 f x1 x2 x3 x4 u x6 x7 x8)
(f t)
(f u) where
_5 = unsafeLens 4
instance Lens.Field6 (Assignment8 f x1 x2 x3 x4 x5 t x7 x8)
(Assignment8 f x1 x2 x3 x4 x5 u x7 x8)
(f t)
(f u) where
_6 = unsafeLens 5
instance Lens.Field7 (Assignment8 f x1 x2 x3 x4 x5 x6 t x8)
(Assignment8 f x1 x2 x3 x4 x5 x6 u x8)
(f t)
(f u) where
_7 = unsafeLens 6
instance Lens.Field8 (Assignment8 f x1 x2 x3 x4 x5 x6 x7 t)
(Assignment8 f x1 x2 x3 x4 x5 x6 x7 u)
(f t)
(f u) where
_8 = unsafeLens 7
type Assignment9 f x1 x2 x3 x4 x5 x6 x7 x8 x9
= Assignment f ('EmptyCtx '::> x1 '::> x2 '::> x3 '::> x4 '::> x5 '::> x6 '::> x7 '::> x8 '::> x9)
instance Lens.Field1 (Assignment9 f t x2 x3 x4 x5 x6 x7 x8 x9)
(Assignment9 f u x2 x3 x4 x5 x6 x7 x8 x9)
(f t)
(f u) where
_1 = unsafeLens 0
instance Lens.Field2 (Assignment9 f x1 t x3 x4 x5 x6 x7 x8 x9)
(Assignment9 f x1 u x3 x4 x5 x6 x7 x8 x9)
(f t)
(f u) where
_2 = unsafeLens 1
instance Lens.Field3 (Assignment9 f x1 x2 t x4 x5 x6 x7 x8 x9)
(Assignment9 f x1 x2 u x4 x5 x6 x7 x8 x9)
(f t)
(f u) where
_3 = unsafeLens 2
instance Lens.Field4 (Assignment9 f x1 x2 x3 t x5 x6 x7 x8 x9)
(Assignment9 f x1 x2 x3 u x5 x6 x7 x8 x9)
(f t)
(f u) where
_4 = unsafeLens 3
instance Lens.Field5 (Assignment9 f x1 x2 x3 x4 t x6 x7 x8 x9)
(Assignment9 f x1 x2 x3 x4 u x6 x7 x8 x9)
(f t)
(f u) where
_5 = unsafeLens 4
instance Lens.Field6 (Assignment9 f x1 x2 x3 x4 x5 t x7 x8 x9)
(Assignment9 f x1 x2 x3 x4 x5 u x7 x8 x9)
(f t)
(f u) where
_6 = unsafeLens 5
instance Lens.Field7 (Assignment9 f x1 x2 x3 x4 x5 x6 t x8 x9)
(Assignment9 f x1 x2 x3 x4 x5 x6 u x8 x9)
(f t)
(f u) where
_7 = unsafeLens 6
instance Lens.Field8 (Assignment9 f x1 x2 x3 x4 x5 x6 x7 t x9)
(Assignment9 f x1 x2 x3 x4 x5 x6 x7 u x9)
(f t)
(f u) where
_8 = unsafeLens 7
instance Lens.Field9 (Assignment9 f x1 x2 x3 x4 x5 x6 x7 x8 t)
(Assignment9 f x1 x2 x3 x4 x5 x6 x7 x8 u)
(f t)
(f u) where
_9 = unsafeLens 8