{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} import Control.Lens import Control.Monad.Fix import Data.Align import qualified Data.AppendMap as AMap import Data.Functor.Misc import Data.Map (Map) import qualified Data.Map as Map import Data.Map.Monoidal (MonoidalMap) import Data.Semigroup import Data.These import Reflex import Reflex.Patch.MapWithMove import Test.Run newtype MyQuery = MyQuery SelectedCount deriving (Show, Read, Eq, Ord, Monoid, Semigroup, Additive, Group) instance Query MyQuery where type QueryResult MyQuery = () crop _ _ = () instance (Ord k, Query a, Eq (QueryResult a), Align (MonoidalMap k)) => Query (Selector k a) where type QueryResult (Selector k a) = Selector k (QueryResult a) crop q r = undefined newtype Selector k a = Selector { unSelector :: MonoidalMap k a } deriving (Show, Read, Eq, Ord, Functor) #if !(MIN_VERSION_monoidal_containers(0,4,1)) deriving instance Ord k => Align (MonoidalMap k) #endif instance (Ord k, Eq a, Monoid a, Align (MonoidalMap k)) => Semigroup (Selector k a) where (Selector a) <> (Selector b) = Selector $ fmapMaybe id $ f a b where f = alignWith $ \case This x -> Just x That y -> Just y These x y -> let z = x `mappend` y in if z == mempty then Nothing else Just z instance (Ord k, Eq a, Monoid a, Align (MonoidalMap k)) => Monoid (Selector k a) where mempty = Selector AMap.empty mappend = (<>) instance (Eq a, Ord k, Group a, Align (MonoidalMap k)) => Group (Selector k a) where negateG = fmap negateG instance (Eq a, Ord k, Group a, Align (MonoidalMap k)) => Additive (Selector k a) main :: IO () main = do [0, 1, 1, 0] <- fmap (map fst . concat) $ runApp (testQueryT testRunWithReplace) () $ map (Just . That) $ [ That (), This (), That () ] [0, 1, 1, 0] <- fmap (map fst . concat) $ runApp (testQueryT testSequenceDMapWithAdjust) () $ map (Just . That) $ [ That (), This (), That () ] [0, 1, 1, 0] <- fmap (map fst . concat) $ runApp (testQueryT testSequenceDMapWithAdjustWithMove) () $ map (Just . That) $ [ That (), This (), That () ] return () testQueryT :: (Reflex t, MonadFix m) => (Event t () -> Event t () -> QueryT t (Selector Int MyQuery) m ()) -> AppIn t () (These () ()) -> m (AppOut t Int Int) testQueryT w (AppIn _ pulse) = do let replace = fmapMaybe (^? here) pulse increment = fmapMaybe (^? there) pulse (_, q) <- runQueryT (w replace increment) $ pure mempty let qDyn = head . AMap.keys . unSelector <$> incrementalToDynamic q return $ AppOut { _appOut_behavior = current qDyn , _appOut_event = updated qDyn } testRunWithReplace :: ( Reflex t , Adjustable t m , MonadHold t m , MonadFix m , MonadQuery t (Selector Int MyQuery) m) => Event t () -> Event t () -> m () testRunWithReplace replace increment = do let w = do n <- count increment queryDyn $ zipDynWith (\x y -> Selector (AMap.singleton (x :: Int) y)) n $ pure $ MyQuery $ SelectedCount 1 _ <- runWithReplace w $ w <$ replace return () testSequenceDMapWithAdjust :: ( Reflex t , Adjustable t m , MonadHold t m , MonadFix m , MonadQuery t (Selector Int MyQuery) m) => Event t () -> Event t () -> m () testSequenceDMapWithAdjust replace increment = do _ <- listHoldWithKey (Map.singleton () ()) (Map.singleton () (Just ()) <$ replace) $ \_ _ -> do n <- count increment queryDyn $ zipDynWith (\x y -> Selector (AMap.singleton (x :: Int) y)) n $ pure $ MyQuery $ SelectedCount 1 return () testSequenceDMapWithAdjustWithMove :: ( Reflex t , Adjustable t m , MonadHold t m , MonadFix m , MonadQuery t (Selector Int MyQuery) m) => Event t () -> Event t () -> m () testSequenceDMapWithAdjustWithMove replace increment = do _ <- listHoldWithKeyWithMove (Map.singleton () ()) (Map.singleton () (Just ()) <$ replace) $ \_ _ -> do n <- count increment queryDyn $ zipDynWith (\x y -> Selector (AMap.singleton (x :: Int) y)) n $ pure $ MyQuery $ SelectedCount 1 return () -- scam it out to test traverseDMapWithAdjustWithMove listHoldWithKeyWithMove :: forall t m k v a. (Ord k, MonadHold t m, Adjustable t m) => Map k v -> Event t (Map k (Maybe v)) -> (k -> v -> m a) -> m (Dynamic t (Map k a)) listHoldWithKeyWithMove m0 m' f = do (n0, n') <- mapMapWithAdjustWithMove f m0 $ ffor m' $ PatchMapWithMove . Map.map (\v -> NodeInfo (maybe From_Delete From_Insert v) Nothing) incrementalToDynamic <$> holdIncremental n0 n' -- -}