@@ -43,6 +43,7 @@ module Reflex.Dynamic
43 , maybeDyn
43 , maybeDyn
44 , eitherDyn
44 , eitherDyn
45 , factorDyn
45 , factorDyn
47 , scanDynMaybe
48 , scanDynMaybe
48 , holdUniqDyn
49 , holdUniqDyn
@@ -76,7 +77,6 @@ module Reflex.Dynamic
76 , unsafeDynamic
77 , unsafeDynamic
79−import Data.Functor.Compose
80import Data.Functor.Misc
80import Data.Functor.Misc
81import Reflex.Class
81import Reflex.Class
@@ -87,11 +87,15 @@ import Data.Align
87import Data.Dependent.Map (DMap)
87import Data.Dependent.Map (DMap)
88import qualified Data.Dependent.Map as DMap
88import qualified Data.Dependent.Map as DMap
89import Data.Dependent.Sum (DSum (..))
89import Data.Dependent.Sum (DSum (..))
90+import Data.Functor.Compose (Compose (Compose), getCompose)
90import Data.GADT.Compare ((:~:) (..), GCompare (..), GEq (..), GOrdering (..))
91import Data.GADT.Compare ((:~:) (..), GCompare (..), GEq (..), GOrdering (..))
91import Data.Map (Map)
92import Data.Map (Map)
92−import Data.Maybe
93+import Data.Maybe (isJust)
93import Data.Monoid ((<>))
94import Data.Monoid ((<>))
94import Data.These
95import Data.These
96+import Generics.SOP ((:.:) (Comp), Code, Generic, I (I), Proxy (Proxy), SListI, SOP (SOP), from, hcmap, hmap, to, unSOP)
97+import Generics.SOP.Distribute (distributeI_NP)
98+import Generics.SOP.DMapUtilities (FunctorWrapTypeListOfLists, dSumToNS, nsOfnpUnCompose, nsToDSum)
96import Debug.Trace
100import Debug.Trace
@@ -308,6 +312,28 @@ eitherDyn = fmap (fmap unpack) . factorDyn . fmap eitherToDSum
308 LeftTag :=> Compose a -> Left $ coerceDynamic a
312 LeftTag :=> Compose a -> Left $ coerceDynamic a
309 RightTag :=> Compose b -> Right $ coerceDynamic b
313 RightTag :=> Compose b -> Right $ coerceDynamic b
315+-- | Use factorDyn and generics-sop to turn a Dynamic of a type into a factored
316+-- Dynamic of a type with Dynamic fields. For example:
318+-- > maybeDyn :: (Reflex t, MonadHold t m, MonadFix m) => Dynamic t (Maybe a) -> m (Dynamic t (Maybe (Dynamic t a)))
319+-- > maybeDyn = factorDynGeneric
321+-- > eitherDyn :: (Reflex t, MonadHold t m, MonadFix m) => Dynamic t (Either a b) -> m (Dynamic t (Either (Dynamic t a) (Dynamic t b)))
322+-- > eitherDyn = factorDynGeneric
323+factorDynGeneric :: forall t m a b. (Reflex t, MonadFix m, MonadHold t m
324+ , Generic a, Generic b
325+ , (Code b) ~ FunctorWrapTypeListOfLists (Dynamic t) (Code a))
326+ => Dynamic t a -> m (Dynamic t b)
327+factorDynGeneric da = do
328+ let dSumDyn = nsToDSum . unSOP . from <$> da -- Dynamic t (DSum (TypeListTag (Code a)) (NP I xs))
329+ dSumDyn' <- factorDyn dSumDyn -- Dynamic t (DSum (TypeListTag (Code a)) (NP I))
330+ let nsnpDyn = dSumToNS <$> dSumDyn' -- Dynamic t (NS (Compose (Dynamic t) (NP I)) (Code a))
331+ sListIC = Proxy :: Proxy SListI
332+ nsnpDyn' = hcmap sListIC (hmap (Comp. I) . distributeI_NP . getCompose) <$> nsnpDyn -- Dynamic t (NS (NP (I :.: Dynamic t)) (Code a))
333+ nsnpDyn'' = nsOfnpUnCompose <$> nsnpDyn' -- Dynamic t (NS (NP I) (Code b))
334+ result = to . SOP <$> nsnpDyn''
311factorDyn :: forall t m k v. (Reflex t, MonadHold t m, GEq k)
337factorDyn :: forall t m k v. (Reflex t, MonadHold t m, GEq k)
312 => Dynamic t (DSum k v) -> m (Dynamic t (DSum k (Compose (Dynamic t) v)))
338 => Dynamic t (DSum k v) -> m (Dynamic t (DSum k (Compose (Dynamic t) v)))
313factorDyn d = buildDynamic (sample (current d) >>= holdKey) update where
339factorDyn d = buildDynamic (sample (current d) >>= holdKey) update where
@@ -359,15 +385,22 @@ demuxed d k =
359 let e = select (demuxSelector d) (Const2 k)
385 let e = select (demuxSelector d) (Const2 k)
360 in unsafeBuildDynamic (fmap (==k) $ sample $ demuxValue d) e
386 in unsafeBuildDynamic (fmap (==k) $ sample $ demuxValue d) e
362--------------------------------------------------------------------------------
389--------------------------------------------------------------------------------
363-- collectDyn
390-- collectDyn
364--------------------------------------------------------------------------------
391--------------------------------------------------------------------------------
366−--TODO: This whole section is badly in need of cleanup
393+-- | This is now deprecated in favor of types from the generics-sop library and
394+-- functions provided in Reflex.Dynamic.CollectDynGeneric
395+-- The generics-sop 'NP' product type takes the place of FHList and HList.
396+-- Utilities to manipulate the NP types (shifting functors from the type into and out of the type-list
397+-- and convert from NP to DMap and DMap to NP are all in Generics.SOP.DMapUtilities
398+-- Equivalent "distribute" and "collect" functions are now in Reflex.Dynamic.CollectDynGeneric
368-- | A heterogeneous list whose type and length are fixed statically. This is
400-- | A heterogeneous list whose type and length are fixed statically. This is
369-- reproduced from the 'HList' package due to integration issues, and because
401-- reproduced from the 'HList' package due to integration issues, and because
370-- very little other functionality from that library is needed.
402-- very little other functionality from that library is needed.
403+{-# DEPRECATED HList, HRevApp, hRevApp, hReverse, hBuild, HBuild' "This interface for type-level lists is being deprecated in favor of the 'NP' type from generics-sop" #-}
371data HList (l::[*]) where
404data HList (l::[*]) where
372 HNil :: HList '[]
405 HNil :: HList '[]
373 HCons :: e -> HList l -> HList (e ': l)
406 HCons :: e -> HList l -> HList (e ': l)
@@ -400,6 +433,7 @@ instance HBuild' (a ': l) r
400 hBuild' l x = hBuild' (HCons x l)
433 hBuild' l x = hBuild' (HCons x l)
402-- | Like 'HList', but with a functor wrapping each element.
435-- | Like 'HList', but with a functor wrapping each element.
436+{-# DEPRECATED FHList,RebuildSortedHList "This interface for type-level lists is being deprecated in favor of the 'NP' type from generics-sop" #-}
403data FHList f l where
437data FHList f l where
404 FHNil :: FHList f '[]
438 FHNil :: FHList f '[]
405 FHCons :: f e -> FHList f l -> FHList f (e ': l)
439 FHCons :: f e -> FHList f l -> FHList f (e ': l)
@@ -417,6 +451,7 @@ instance GCompare (HListPtr l) where -- Warning: This ordering can't change, dma
417 HTailPtr a `gcompare` HTailPtr b = a `gcompare` b
451 HTailPtr a `gcompare` HTailPtr b = a `gcompare` b
419-- | A typed index into a typed heterogeneous list.
453-- | A typed index into a typed heterogeneous list.
454+{-# DEPRECATED HListPtr "Use 'Generics.SOP.DMapUtiltiies.TypeListTag' instead" #-}
420data HListPtr l a where
455data HListPtr l a where
421 HHeadPtr :: HListPtr (h ': t) h
456 HHeadPtr :: HListPtr (h ': t) h
422 HTailPtr :: HListPtr t a -> HListPtr (h ': t) a
457 HTailPtr :: HListPtr t a -> HListPtr (h ': t) a
@@ -424,6 +459,7 @@ data HListPtr l a where
424deriving instance Eq (HListPtr l a)
459deriving instance Eq (HListPtr l a)
425deriving instance Ord (HListPtr l a)
460deriving instance Ord (HListPtr l a)
462+{-# DEPRECATED fhlistToDMap "Use generics-sop 'NP' for your functor wrapped type-list and then 'Generics.SOP.DMapUtilities.npToDMap'" #-}
427fhlistToDMap :: forall (f :: * -> *) l. FHList f l -> DMap (HListPtr l) f
463fhlistToDMap :: forall (f :: * -> *) l. FHList f l -> DMap (HListPtr l) f
428fhlistToDMap = DMap.fromList . go
464fhlistToDMap = DMap.fromList . go
429 where go :: forall l'. FHList f l' -> [DSum (HListPtr l') f]
465 where go :: forall l'. FHList f l' -> [DSum (HListPtr l') f]
@@ -453,17 +489,20 @@ instance RebuildSortedHList t => RebuildSortedHList (h ': t) where
453 ((HHeadPtr :=> Identity h) : t) -> HCons h . rebuildSortedHList . map (\(HTailPtr p :=> v) -> p :=> v) $ t
489 ((HHeadPtr :=> Identity h) : t) -> HCons h . rebuildSortedHList . map (\(HTailPtr p :=> v) -> p :=> v) $ t
454 _ -> error "rebuildSortedHList{h':t}: non-empty list with HHeadPtr expected"
490 _ -> error "rebuildSortedHList{h':t}: non-empty list with HHeadPtr expected"
492+{-# DEPRECATED dmapToHList "Use generics-sop 'NP' for your functor wrapped type-list and then 'Generics.SOP.DMapUtilities.dMapToNP'" #-}
456dmapToHList :: forall l. RebuildSortedHList l => DMap (HListPtr l) Identity -> HList l
493dmapToHList :: forall l. RebuildSortedHList l => DMap (HListPtr l) Identity -> HList l
457dmapToHList = rebuildSortedHList . DMap.toList
494dmapToHList = rebuildSortedHList . DMap.toList
459-- | Collect a hetereogeneous list whose elements are all 'Dynamic's into a
496-- | Collect a hetereogeneous list whose elements are all 'Dynamic's into a
460-- single 'Dynamic' whose value represents the current values of all of the
497-- single 'Dynamic' whose value represents the current values of all of the
461-- input 'Dynamic's.
498-- input 'Dynamic's.
499+{-# DEPRECATED distributeFHListOverDynPure "Use the generics-sop 'NP' type for functor-wrapped type-lists and then 'Reflex.Dynamic.CollectDynGeneric.collectDynNP' " #-}
462distributeFHListOverDynPure :: (Reflex t, RebuildSortedHList l) => FHList (Dynamic t) l -> Dynamic t (HList l)
500distributeFHListOverDynPure :: (Reflex t, RebuildSortedHList l) => FHList (Dynamic t) l -> Dynamic t (HList l)
463distributeFHListOverDynPure l = fmap dmapToHList $ distributeDMapOverDynPure $ fhlistToDMap l
501distributeFHListOverDynPure l = fmap dmapToHList $ distributeDMapOverDynPure $ fhlistToDMap l
465-- | Indicates that all elements in a type-level list are applications of the
503-- | Indicates that all elements in a type-level list are applications of the
466-- same functor.
504-- same functor.
505+{-# DEPRECATED AllAreFunctors "This functionality is provided for generics-sop 'NP' via 'Generics.SOP.DMapUtilties.npUnCompose' and 'Generics.SOP.DMapUtilities.npReCompose'" #-}
467class AllAreFunctors (f :: a -> *) (l :: [a]) where
506class AllAreFunctors (f :: a -> *) (l :: [a]) where
468 type FunctorList f l :: [*]
507 type FunctorList f l :: [*]
469 toFHList :: HList (FunctorList f l) -> FHList f l
508 toFHList :: HList (FunctorList f l) -> FHList f l
@@ -489,7 +528,8 @@ instance AllAreFunctors f t => AllAreFunctors f (h ': t) where
490-- | Convert a datastructure whose constituent parts are all 'Dynamic's into a
529-- | Convert a datastructure whose constituent parts are all 'Dynamic's into a
491-- single 'Dynamic' whose value represents all the current values of the input's
530-- single 'Dynamic' whose value represents all the current values of the input's
492−-- constituent 'Dynamic's.
531+-- consitutent 'Dynamic's.
532+{-# DEPRECATED collectDynPure "Use 'Reflex.Dynamic.CollectDynGeneric.collectDynGeneric' instead." #-}
493collectDynPure :: ( RebuildSortedHList (HListElems b)
533collectDynPure :: ( RebuildSortedHList (HListElems b)
494 , IsHList a, IsHList b
534 , IsHList a, IsHList b
495 , AllAreFunctors (Dynamic t) (HListElems b)
535 , AllAreFunctors (Dynamic t) (HListElems b)