2{-# LANGUAGE ConstraintKinds #-}
3{-# LANGUAGE FlexibleInstances #-}
4{-# LANGUAGE FunctionalDependencies #-}
5{-# LANGUAGE LambdaCase #-}
6{-# LANGUAGE MultiParamTypeClasses #-}
7{-# LANGUAGE RankNTypes #-}
8{-# LANGUAGE ScopedTypeVariables #-}
9{-# LANGUAGE TypeFamilies #-}
10{-# LANGUAGE UndecidableInstances #-}
11#ifdef USE_REFLEX_OPTIMIZER
12{-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-}
14module Reflex.Adjustable.Class
16 -- * The Adjustable typeclass
18 , sequenceDMapWithAdjust
19 , sequenceDMapWithAdjustWithMove
20 , mapMapWithAdjustWithMove
21 -- * Deprecated aliases
25import Control.Monad.Identity
26import Control.Monad.Reader
27import Data.Dependent.Map (DMap, GCompare (..))
28import qualified Data.Dependent.Map as DMap
29import Data.Functor.Constant
30import Data.Functor.Misc
31import Data.IntMap.Strict (IntMap)
32import qualified Data.IntMap.Strict as IntMap
36import Reflex.Patch.DMapWithMove
38-- | A 'Monad' that supports adjustment over time. After an action has been
39-- run, if the given events fire, it will adjust itself so that its net effect
40-- is as though it had originally been run with the new value. Note that there
41-- is some issue here with persistent side-effects: obviously, IO (and some
42-- other side-effects) cannot be undone, so it is up to the instance implementer
43-- to determine what the best meaning for this class is in such cases.
44class (Reflex t, Monad m) => Adjustable t m | m -> t where
50 traverseIntMapWithKeyWithAdjust
51 :: (IntMap.Key -> v -> m v')
53 -> Event t (PatchIntMap v)
54 -> m (IntMap v', Event t (PatchIntMap v'))
56 traverseDMapWithKeyWithAdjust
58 => (forall a. k a -> v a -> m (v' a))
60 -> Event t (PatchDMap k v)
61 -> m (DMap k v', Event t (PatchDMap k v'))
62 {-# INLINABLE traverseDMapWithKeyWithAdjust #-}
63 traverseDMapWithKeyWithAdjust f dm0 dm' = fmap (fmap (fmap fromPatchWithMove)) $
64 traverseDMapWithKeyWithAdjustWithMove f dm0 $ fmap toPatchWithMove dm'
66 toPatchWithMove (PatchDMap m) = PatchDMapWithMove $ DMap.map toNodeInfoWithMove m
67 toNodeInfoWithMove = \case
68 ComposeMaybe (Just v) -> NodeInfo (From_Insert v) $ ComposeMaybe Nothing
69 ComposeMaybe Nothing -> NodeInfo From_Delete $ ComposeMaybe Nothing
70 fromPatchWithMove (PatchDMapWithMove m) = PatchDMap $ DMap.map fromNodeInfoWithMove m
71 fromNodeInfoWithMove (NodeInfo from _) = ComposeMaybe $ case from of
72 From_Insert v -> Just v
73 From_Delete -> Nothing
74 From_Move _ -> error "traverseDMapWithKeyWithAdjust: implementation of traverseDMapWithKeyWithAdjustWithMove inserted spurious move"
76 traverseDMapWithKeyWithAdjustWithMove
78 => (forall a. k a -> v a -> m (v' a))
80 -> Event t (PatchDMapWithMove k v)
81 -> m (DMap k v', Event t (PatchDMapWithMove k v'))
83instance Adjustable t m => Adjustable t (ReaderT r m) where
84 runWithReplace a0 a' = do
86 lift $ runWithReplace (runReaderT a0 r) $ fmap (`runReaderT` r) a'
87 traverseIntMapWithKeyWithAdjust f dm0 dm' = do
89 lift $ traverseIntMapWithKeyWithAdjust (\k v -> runReaderT (f k v) r) dm0 dm'
90 traverseDMapWithKeyWithAdjust f dm0 dm' = do
92 lift $ traverseDMapWithKeyWithAdjust (\k v -> runReaderT (f k v) r) dm0 dm'
93 traverseDMapWithKeyWithAdjustWithMove f dm0 dm' = do
95 lift $ traverseDMapWithKeyWithAdjustWithMove (\k v -> runReaderT (f k v) r) dm0 dm'
97sequenceDMapWithAdjust :: (GCompare k, Adjustable t m) => DMap k m -> Event t (PatchDMap k m) -> m (DMap k Identity, Event t (PatchDMap k Identity))
98sequenceDMapWithAdjust = traverseDMapWithKeyWithAdjust $ \_ -> fmap Identity
100sequenceDMapWithAdjustWithMove :: (GCompare k, Adjustable t m) => DMap k m -> Event t (PatchDMapWithMove k m) -> m (DMap k Identity, Event t (PatchDMapWithMove k Identity))
101sequenceDMapWithAdjustWithMove = traverseDMapWithKeyWithAdjustWithMove $ \_ -> fmap Identity
103mapMapWithAdjustWithMove :: forall t m k v v'. (Adjustable t m, Ord k) => (k -> v -> m v') -> Map k v -> Event t (PatchMapWithMove k v) -> m (Map k v', Event t (PatchMapWithMove k v'))
104mapMapWithAdjustWithMove f m0 m' = do
105 (out0 :: DMap (Const2 k v) (Constant v'), out') <- traverseDMapWithKeyWithAdjustWithMove (\(Const2 k) (Identity v) -> Constant <$> f k v) (mapToDMap m0) (const2PatchDMapWithMoveWith Identity <$> m')
106 return (dmapToMapWith (\(Constant v') -> v') out0, patchDMapWithMoveToPatchMapWithMoveWith (\(Constant v') -> v') <$> out')
108--------------------------------------------------------------------------------
109-- Deprecated functions
110--------------------------------------------------------------------------------
112{-# DEPRECATED MonadAdjust "Use Adjustable instead" #-}
113type MonadAdjust = Adjustable
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list