{-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE CPP #-} #if __GLASGOW_HASKELL__ < 710 {-# LANGUAGE OverlappingInstances #-} #endif module Data.Container.Hetero where --import Flowbox.Prelude hiding (Indexable, index, Repr, repr) import Prelude --import Control.Error.Util (hush) import Data.Container.Class --import Data.Constraint.Void --import Data.Convert.Errors (TypeMismatch (TypeMismatch)) import Data.Typeable hiding (cast) import Unsafe.Coerce (unsafeCoerce) import Data.Container.Poly --import Data.Reprx --- === Unified values === --data Unified ctx where -- Unified :: (ctx a, UnifiedEl a) => a -> Unified ctx --type UnifiedEl a = (Typeable a, Show a) ---- instances --instance Show (Unified ctx) where -- show (Unified a) = show a --instance Typeable a => MaybeConvertible (Unified ctx) TypeMismatch a where -- tryConvert (Unified u) = if tu == ta then Right $ unsafeCoerce u -- else Left $ TypeMismatch tu ta -- where tu = typeOf u -- ta = typeOf (undefined :: a) --instance {-# OVERLAPPABLE #-} Castable (Unified ctx) a where cast (Unified a) = unsafeCoerce a --instance {-# OVERLAPPABLE #-} (ctx a, UnifiedEl a) => Castable a (Unified ctx) where cast = Unified -- === Ptr === newtype Ptr i a = Ptr i deriving (Show) newtype HPtr i m a = HPtr (Ptr i (m a)) deriving (Show) class PtrFrom p i | p -> i where ptrFrom :: p -> Ptr i a --class (Container cont (Ptr i a) a, Container cont p a) => IsPtr cont p i a where -- ptr :: cont -> p -> Ptr i a ---- injective TF --class PtrTarget (a :: * -> *) (b :: (* -> *) -> *) c | a b -> c, c -> a b --where --instance PtrTarget (HPtr i h) a {- = -} (h (a (HPtr i h))) --instance PtrTarget (Ptr i) a {- = -} (a (Ptr i)) ---- instances --instance Repr s i => Repr s (HPtr i m a) where repr (HPtr p) = "HPtr" <+> repr p --instance Repr s i => Repr s (Ptr i a) where repr (Ptr i) = "Ptr " <+> repr i --type instance IxType (Ptr i a) = a --type instance IxType (HPtr i m a) = a --instance Convertible i (Ptr i a) where convert = Ptr --instance Convertible (Ptr i a) i where convert = ptrIdx --instance Convertible i (HPtr i m a) where convert = HPtr . convert --instance Convertible (HPtr i m a) i where convert = ptrIdx --instance Convertible (Ptr i (m a)) (HPtr i m a) where convert = HPtr class PtrIdx p i | p -> i where ptrIdx :: p -> i instance PtrIdx (Ptr i a) i where ptrIdx (Ptr i) = i instance PtrIdx (HPtr i m a) i where ptrIdx (HPtr p) = ptrIdx p instance {-# OVERLAPPABLE #-} (p ~ i) => PtrFrom p i where ptrFrom = Ptr instance PtrFrom (Ptr i a) i where ptrFrom (Ptr i) = Ptr i ----- === Hetero Containers === --type Hetero ctx cont = HeteroContainer (cont (Unified ctx)) --type Hetero' cont = Hetero Void1 cont --newtype HeteroContainer cont = HeteroContainer { _cont :: cont } deriving (Show, Functor, Foldable, Traversable) --makeLenses ''HeteroContainer ---- basic instances --type instance ElementByIx idx (HeteroContainer cont) = IxType idx --type instance IndexOf el (HeteroContainer cont) = Ptr (IndexOf el cont) el ----instance HasContainer (HeteroContainer c) (HeteroContainer c) where ---- container = id --instance Default cont => Default (HeteroContainer cont) where -- def = HeteroContainer def --instance Monoid cont => Monoid (HeteroContainer cont) where -- mempty = HeteroContainer mempty -- (HeteroContainer c) `mappend` (HeteroContainer c') = HeteroContainer $ c <> c' ---- container instances --type HeteroTransCtx idx ctx a cont idx' el = ( ElementOf cont ~ el -- , el ~ Unified ctx -- , ctx a, UnifiedEl a -- , IsoConvertible idx idx' -- ) ------class (IndexOf el cont ~ idx, ElementByIx idx cont ~ el, Measurable cont) => Container cont idx el where ------ elems :: cont -> [el] ------ indexes :: cont -> [idx] ----instance (idx ~ Ptr (IndexOf a cont) a) => Container (HeteroContainer cont) idx a ----instance Measurable (HeteroContainer cont) ------ TODO: TO END ^^^ ----instance (HeteroTransCtx idx ctx a cont idx' el, Appendable' cont idx' el) ---- => Appendable' (HeteroContainer cont) idx a where ---- append' a (HeteroContainer cont) = (HeteroContainer cont', convert idx') where ---- (cont', idx') = append' (Unified a :: Unified ctx) cont ----instance (HeteroTransCtx idx ctx a cont idx' el, Prependable cont idx' el) ---- => Prependable (HeteroContainer cont) idx a where ---- prepend' a (HeteroContainer cont) = (HeteroContainer cont', convert idx') where ---- (cont', idx') = prepend' (Unified a :: Unified ctx) cont ----instance (HeteroTransCtx idx ctx a cont idx' el, Updatable cont idx' el) ---- => Updatable (HeteroContainer cont) idx a where ---- update idx a = fmap $ update (convert idx) (Unified a :: Unified ctx) ----instance (HeteroTransCtx idx ctx a cont idx' el, Insertable cont idx' el) ---- => Insertable (HeteroContainer cont) idx a where ---- insert idx a = fmap $ insert (convert idx) (Unified a :: Unified ctx) ---- unsafeInsert idx a = fmap $ unsafeInsert (convert idx) (Unified a :: Unified ctx) ----instance (HeteroTransCtx idx ctx a cont idx' el, Indexable cont idx' el, Convertible (Unified ctx) a) ---- => Indexable (HeteroContainer cont) idx a where ---- index idx (HeteroContainer cont) = convert (index (convert idx) cont :: Unified ctx) ----instance (HeteroTransCtx idx ctx a cont idx' el, Indexable (Unsafe cont) idx' el, Convertible (Unified ctx) a) ---- => Indexable (Unsafe (HeteroContainer cont)) idx a where ---- index idx (unwrap -> (HeteroContainer cont)) = cast $ (unsafely (index $ convert idx) cont :: Unified ctx) ----instance (Indexable2 opts a idx el) => Indexable2 opts (Resizable s a) idx el where index2 opts idx = index2 opts idx . unwrap