@@ -38,6 +38,7 @@ module Reflex.Dynamic
3838 , maybeDyn
3939 , eitherDyn
4040 , factorDyn
41+ , factorDynGeneric
4142 , scanDyn
4243 , scanDynMaybe
4344 , holdUniqDyn
@@ -57,15 +58,6 @@ module Reflex.Dynamic
5758 , Demux
5859 , demux
5960 , demuxed
60− -- Things that probably aren't very useful:
61− , HList (..)
62− , FHList (..)
63− , collectDynPure
64− , RebuildSortedHList (..)
65− , IsHList (..)
66− , AllAreFunctors (..)
67− , HListPtr (..)
68− , distributeFHListOverDynPure
6961 -- Unsafe
7062 , unsafeDynamic
7163 -- * Deprecated functions
@@ -87,9 +79,17 @@ module Reflex.Dynamic
8779 , tagDyn
8880 , uniqDyn
8981 , uniqDynBy
82+ -- Things that probably aren't very useful, and are also deprecated
83+ , HList (..)
84+ , FHList (..)
85+ , collectDynPure
86+ , RebuildSortedHList (..)
87+ , IsHList (..)
88+ , AllAreFunctors (..)
89+ , HListPtr (..)
90+ , distributeFHListOverDynPure
9091 ) where
9192
92−import Data.Functor.Compose
9393import Data.Functor.Misc
9494import Reflex.Class
9595
@@ -101,11 +101,15 @@ import Data.Align
101101import Data.Dependent.Map (DMap)
102102import qualified Data.Dependent.Map as DMap
103103import Data.Dependent.Sum (DSum (..))
104+import Data.Functor.Compose (Compose (Compose), getCompose)
104105import Data.GADT.Compare ((:~:) (..), GCompare (..), GEq (..), GOrdering (..))
105106import Data.Map (Map)
106−import Data.Maybe
107+import Data.Maybe (isJust)
107108import Data.Monoid
108109import Data.These
110+import Generics.SOP ((:.:) (Comp), Code, Generic, I (I), Proxy (Proxy), SListI, SOP (SOP), from, hcmap, hmap, to, unSOP)
111+import Generics.SOP.Distribute (distributeI_NP)
112+import Generics.SOP.DMapUtilities (FunctorWrapTypeListOfLists, dSumToNS, nsOfnpUnCompose, nsToDSum)
109113
110114import Debug.Trace
111115
@@ -329,6 +333,29 @@ factorDyn d = do
329333 o0 <- getInitial --TODO: Figure out how to get this to run inside something like the first argument to buildDynamic
330334 holdDyn o0 update
331335
336+-- | Use factorDyn and generics-sop to turn a Dynamic of a type into a factored
337+-- Dynamic of a type with Dynamic fields. For example:
338+--
339+-- > maybeDyn :: (Reflex t, MonadHold t m, MonadFix m) => Dynamic t (Maybe a) -> m (Dynamic t (Maybe (Dynamic t a)))
340+-- > maybeDyn = factorDynGeneric
341+--
342+-- > eitherDyn :: (Reflex t, MonadHold t m, MonadFix m) => Dynamic t (Either a b) -> m (Dynamic t (Either (Dynamic t a) (Dynamic t b)))
343+-- > eitherDyn = factorDynGeneric
344+
345+factorDynGeneric :: forall t m a b. (Reflex t, MonadFix m, MonadHold t m
346+ , Generic a, Generic b
347+ , (Code b) ~ FunctorWrapTypeListOfLists (Dynamic t) (Code a))
348+ => Dynamic t a -> m (Dynamic t b)
349+factorDynGeneric da = do
350+ let dSumDyn = nsToDSum . unSOP . from <$> da -- Dynamic t (DSum (TypeListTag (Code a)) (NP I xs))
351+ dSumDyn' <- factorDyn dSumDyn -- Dynamic t (DSum (TypeListTag (Code a)) (NP I))
352+ let nsnpDyn = dSumToNS <$> dSumDyn' -- Dynamic t (NS (Compose (Dynamic t) (NP I)) (Code a))
353+ sListIC = Proxy :: Proxy SListI
354+ nsnpDyn' = hcmap sListIC (hmap (Comp. I) . distributeI_NP . getCompose) <$> nsnpDyn -- Dynamic t (NS (NP (I :.: Dynamic t)) (Code a))
355+ nsnpDyn'' = nsOfnpUnCompose <$> nsnpDyn' -- Dynamic t (NS (NP I) (Code b))
356+ result = to . SOP <$> nsnpDyn''
357+ return result
358+
332359--------------------------------------------------------------------------------
333360-- Demux
334361--------------------------------------------------------------------------------
@@ -366,15 +393,22 @@ demuxed d k =
366393 let e = select (demuxSelector d) (Const2 k)
367394 in unsafeBuildDynamic (fmap (==k) $ sample $ demuxValue d) e
368395
396+
369397--------------------------------------------------------------------------------
370398-- collectDyn
371399--------------------------------------------------------------------------------
372400
373−--TODO: This whole section is badly in need of cleanup
401+-- | This is now deprecated in favor of types from the generics-sop library and
402+-- functions provided in Reflex.Dynamic.CollectDynGeneric
403+-- The generics-sop 'NP' product type takes the place of FHList and HList.
404+-- Utilities to manipulate the NP types (shifting functors from the type into and out of the type-list
405+-- and convert from NP to DMap and DMap to NP are all in Generics.SOP.DMapUtilities
406+-- Equivalent "distribute" and "collect" functions are now in Reflex.Dynamic.CollectDynGeneric
374407
375408-- | A heterogeneous list whose type and length are fixed statically. This is
376409-- reproduced from the 'HList' package due to integration issues, and because
377410-- very little other functionality from that library is needed.
411+{-# 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" #-}
378412data HList (l::[*]) where
379413 HNil :: HList '[]
380414 HCons :: e -> HList l -> HList (e ': l)
@@ -407,6 +441,7 @@ instance HBuild' (a ': l) r
407441 hBuild' l x = hBuild' (HCons x l)
408442
409443-- | Like 'HList', but with a functor wrapping each element.
444+{-# DEPRECATED FHList,RebuildSortedHList "This interface for type-level lists is being deprecated in favor of the 'NP' type from generics-sop" #-}
410445data FHList f l where
411446 FHNil :: FHList f '[]
412447 FHCons :: f e -> FHList f l -> FHList f (e ': l)
@@ -433,6 +468,7 @@ instance GCompare (HListPtr l) where -- Warning: This ordering can't change, dma
433468 HTailPtr a `gcompare` HTailPtr b = a `gcompare` b
434469
435470-- | A typed index into a typed heterogeneous list.
471+{-# DEPRECATED HListPtr "Use 'Generics.SOP.DMapUtiltiies.TypeListTag' instead" #-}
436472data HListPtr l a where
437473 HHeadPtr :: HListPtr (h ': t) h
438474 HTailPtr :: HListPtr t a -> HListPtr (h ': t) a
@@ -440,6 +476,7 @@ data HListPtr l a where
440476deriving instance Eq (HListPtr l a)
441477deriving instance Ord (HListPtr l a)
442478
479+{-# DEPRECATED fhlistToDMap "Use generics-sop 'NP' for your functor wrapped type-list and then 'Generics.SOP.DMapUtilities.npToDMap'" #-}
443480fhlistToDMap :: forall (f :: * -> *) l. FHList f l -> DMap (HListPtr l) f
444481fhlistToDMap = DMap.fromList . go
445482 where go :: forall l'. FHList f l' -> [DSum (HListPtr l') f]
@@ -469,17 +506,20 @@ instance RebuildSortedHList t => RebuildSortedHList (h ': t) where
469506 ((HHeadPtr :=> Identity h) : t) -> HCons h . rebuildSortedHList . map (\(HTailPtr p :=> v) -> p :=> v) $ t
470507 _ -> error "rebuildSortedHList{h':t}: non-empty list with HHeadPtr expected"
471508
509+{-# DEPRECATED dmapToHList "Use generics-sop 'NP' for your functor wrapped type-list and then 'Generics.SOP.DMapUtilities.dMapToNP'" #-}
472510dmapToHList :: forall l. RebuildSortedHList l => DMap (HListPtr l) Identity -> HList l
473511dmapToHList = rebuildSortedHList . DMap.toList
474512
475513-- | Collect a hetereogeneous list whose elements are all 'Dynamic's into a
476514-- single 'Dynamic' whose value represents the current values of all of the
477515-- input 'Dynamic's.
516+{-# DEPRECATED distributeFHListOverDynPure "Use the generics-sop 'NP' type for functor-wrapped type-lists and then 'Reflex.Dynamic.CollectDynGeneric.collectDynNP' " #-}
478517distributeFHListOverDynPure :: (Reflex t, RebuildSortedHList l) => FHList (Dynamic t) l -> Dynamic t (HList l)
479518distributeFHListOverDynPure l = fmap dmapToHList $ distributeDMapOverDynPure $ fhlistToDMap l
480519
481520-- | Indicates that all elements in a type-level list are applications of the
482521-- same functor.
522+{-# DEPRECATED AllAreFunctors "This functionality is provided for generics-sop 'NP' via 'Generics.SOP.DMapUtilties.npUnCompose' and 'Generics.SOP.DMapUtilities.npReCompose'" #-}
483523class AllAreFunctors (f :: a -> *) (l :: [a]) where
484524 type FunctorList f l :: [*]
485525 toFHList :: HList (FunctorList f l) -> FHList f l
@@ -506,6 +546,7 @@ instance AllAreFunctors f t => AllAreFunctors f (h ': t) where
506546-- | Convert a datastructure whose constituent parts are all 'Dynamic's into a
507547-- single 'Dynamic' whose value represents all the current values of the input's
508548-- consitutent 'Dynamic's.
549+{-# DEPRECATED collectDynPure "Use 'Reflex.Dynamic.CollectDynGeneric.collectDynGeneric' instead." #-}
509550collectDynPure :: ( RebuildSortedHList (HListElems b)
510551 , IsHList a, IsHList b
511552 , AllAreFunctors (Dynamic t) (HListElems b)