2Module: Reflex.BehaviorWriter.Base
3Description: Implementation of BehaviorWriter
6{-# LANGUAGE FlexibleInstances #-}
8{-# LANGUAGE GeneralizedNewtypeDeriving #-}
9{-# LANGUAGE MultiParamTypeClasses #-}
10{-# LANGUAGE RankNTypes #-}
11{-# LANGUAGE ScopedTypeVariables #-}
12{-# LANGUAGE TypeFamilies #-}
13{-# LANGUAGE UndecidableInstances #-}
14{-# LANGUAGE StandaloneDeriving #-}
15#ifdef USE_REFLEX_OPTIMIZER
16{-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-}
18module Reflex.BehaviorWriter.Base
19 ( BehaviorWriterT (..)
24import Control.Monad.Exception
25import Control.Monad.Identity
26import Control.Monad.IO.Class
27import Control.Monad.Morph
28import Control.Monad.Reader
29import Control.Monad.Ref
30import Control.Monad.State.Strict
31import Data.Dependent.Map (DMap)
32import qualified Data.Dependent.Map as DMap
33import Data.Functor.Misc
34import Data.IntMap (IntMap)
35import qualified Data.IntMap as IntMap
37import qualified Data.Map as Map
38import Data.Some (Some)
41import Reflex.Adjustable.Class
42import Reflex.BehaviorWriter.Class
43import Reflex.Host.Class
44import Reflex.PerformEvent.Class
45import Reflex.PostBuild.Class
46import Reflex.Query.Class
47import Reflex.Requester.Class
48import Reflex.TriggerEvent.Class
50-- | A basic implementation of 'BehaviorWriter'.
51newtype BehaviorWriterT t w m a = BehaviorWriterT { unBehaviorWriterT :: StateT [Behavior t w] m a }
52 -- The list is kept in reverse order
65-- | Run a 'BehaviorWriterT' action. The behavior writer output will be provided
66-- along with the result of the action.
67runBehaviorWriterT :: (Monad m, Reflex t, Monoid w) => BehaviorWriterT t w m a -> m (a, Behavior t w)
68runBehaviorWriterT (BehaviorWriterT a) = do
69 (result, ws) <- runStateT a []
70 return (result, mconcat $ reverse ws)
72-- | Map a function over the output of a 'BehaviorWriterT'.
73withBehaviorWriterT :: (Monoid w, Monoid w', Reflex t, MonadHold t m)
75 -> BehaviorWriterT t w m a
76 -> BehaviorWriterT t w' m a
77withBehaviorWriterT f dw = do
79 (r, d) <- runBehaviorWriterT dw
85deriving instance MonadHold t m => MonadHold t (BehaviorWriterT t w m)
86deriving instance MonadSample t m => MonadSample t (BehaviorWriterT t w m)
88instance MonadRef m => MonadRef (BehaviorWriterT t w m) where
89 type Ref (BehaviorWriterT t w m) = Ref m
90 newRef = lift . newRef
91 readRef = lift . readRef
92 writeRef r = lift . writeRef r
94instance MonadAtomicRef m => MonadAtomicRef (BehaviorWriterT t w m) where
95 atomicModifyRef r = lift . atomicModifyRef r
97instance MonadReflexCreateTrigger t m => MonadReflexCreateTrigger t (BehaviorWriterT t w m) where
98 newEventWithTrigger = lift . newEventWithTrigger
99 newFanEventWithTrigger f = lift $ newFanEventWithTrigger f
101instance (Monad m, Monoid w, Reflex t) => BehaviorWriter t w (BehaviorWriterT t w m) where
102 tellBehavior w = BehaviorWriterT $ modify (w :)
104instance MonadReader r m => MonadReader r (BehaviorWriterT t w m) where
106 local f (BehaviorWriterT a) = BehaviorWriterT $ mapStateT (local f) a
107 reader = lift . reader
109instance PerformEvent t m => PerformEvent t (BehaviorWriterT t w m) where
110 type Performable (BehaviorWriterT t w m) = Performable m
111 performEvent_ = lift . performEvent_
112 performEvent = lift . performEvent
114instance TriggerEvent t m => TriggerEvent t (BehaviorWriterT t w m) where
115 newTriggerEvent = lift newTriggerEvent
116 newTriggerEventWithOnComplete = lift newTriggerEventWithOnComplete
117 newEventWithLazyTriggerWithOnComplete = lift . newEventWithLazyTriggerWithOnComplete
119instance PostBuild t m => PostBuild t (BehaviorWriterT t w m) where
120 getPostBuild = lift getPostBuild
122instance MonadState s m => MonadState s (BehaviorWriterT t w m) where
126instance Requester t m => Requester t (BehaviorWriterT t w m) where
127 type Request (BehaviorWriterT t w m) = Request m
128 type Response (BehaviorWriterT t w m) = Response m
129 requesting = lift . requesting
130 requesting_ = lift . requesting_
132instance (MonadQuery t q m, Monad m) => MonadQuery t q (BehaviorWriterT t w m) where
133 tellQueryIncremental = lift . tellQueryIncremental
134 askQueryResult = lift askQueryResult
135 queryIncremental = lift . queryIncremental
137instance (Adjustable t m, Monoid w, MonadHold t m, Reflex t) => Adjustable t (BehaviorWriterT t w m) where
138 runWithReplace a0 a' = do
139 (result0, result') <- lift $ runWithReplace (runBehaviorWriterT a0) $ runBehaviorWriterT <$> a'
140 tellBehavior . join =<< hold (snd result0) (snd <$> result')
141 return (fst result0, fst <$> result')
142 traverseIntMapWithKeyWithAdjust = traverseIntMapWithKeyWithAdjustImpl traverseIntMapWithKeyWithAdjust
143 traverseDMapWithKeyWithAdjustWithMove = traverseDMapWithKeyWithAdjustImpl traverseDMapWithKeyWithAdjustWithMove mapPatchDMapWithMove weakenPatchDMapWithMoveWith
145traverseIntMapWithKeyWithAdjustImpl
146 :: forall t w v' p p' v m.
147 ( PatchTarget (p' (Behavior t w)) ~ IntMap (Behavior t w)
148 , Patch (p' (Behavior t w))
155 => ( (IntMap.Key -> v -> m (v', Behavior t w))
158 -> m (IntMap (v', Behavior t w), Event t (p (v', Behavior t w)))
160 -> (IntMap.Key -> v -> BehaviorWriterT t w m v')
163 -> BehaviorWriterT t w m (IntMap v', Event t (p v'))
164traverseIntMapWithKeyWithAdjustImpl base f (dm0 :: IntMap v) dm' = do
165 (result0, result') <- lift $ base (\k v -> runBehaviorWriterT $ f k v) dm0 dm'
166 let liftedResult0 = fmap fst result0
167 liftedResult' = fmap (fmap fst) result'
168 liftedWritten0 :: IntMap (Behavior t w)
169 liftedWritten0 = fmap snd result0
170 liftedWritten' = fmap (fmap snd) result'
171 i <- holdIncremental liftedWritten0 liftedWritten'
172 tellBehavior $ pull $ do
173 m <- sample $ currentIncremental i
174 mconcat . IntMap.elems <$> traverse sample m
175 return (liftedResult0, liftedResult')
177newtype BehaviorWriterTLoweredResult t w v a = BehaviorWriterTLoweredResult (v a, Behavior t w)
179traverseDMapWithKeyWithAdjustImpl
180 :: forall t w k v' p p' v m.
181 ( PatchTarget (p' (Some k) (Behavior t w)) ~ Map (Some k) (Behavior t w)
182 , Patch (p' (Some k) (Behavior t w))
187 => ( (forall a. k a -> v a -> m (BehaviorWriterTLoweredResult t w v' a))
190 -> m (DMap k (BehaviorWriterTLoweredResult t w v'), Event t (p k (BehaviorWriterTLoweredResult t w v')))
192 -> ((forall a. BehaviorWriterTLoweredResult t w v' a -> v' a) -> p k (BehaviorWriterTLoweredResult t w v') -> p k v')
193 -> ((forall a. BehaviorWriterTLoweredResult t w v' a -> Behavior t w) -> p k (BehaviorWriterTLoweredResult t w v') -> p' (Some k) (Behavior t w))
194 -> (forall a. k a -> v a -> BehaviorWriterT t w m (v' a))
197 -> BehaviorWriterT t w m (DMap k v', Event t (p k v'))
198traverseDMapWithKeyWithAdjustImpl base mapPatch weakenPatchWith f (dm0 :: DMap k v) dm' = do
199 (result0, result') <- lift $ base (\k v -> fmap BehaviorWriterTLoweredResult $ runBehaviorWriterT $ f k v) dm0 dm'
200 let getValue (BehaviorWriterTLoweredResult (v, _)) = v
201 getWritten (BehaviorWriterTLoweredResult (_, w)) = w
202 liftedResult0 = DMap.map getValue result0
203 liftedResult' = ffor result' $ mapPatch getValue
204 liftedWritten0 :: Map (Some k) (Behavior t w)
205 liftedWritten0 = weakenDMapWith getWritten result0
206 liftedWritten' = ffor result' $ weakenPatchWith getWritten
207 i <- holdIncremental liftedWritten0 liftedWritten'
208 tellBehavior $ pull $ do
209 m <- sample $ currentIncremental i
210 mconcat . Map.elems <$> traverse sample m
211 return (liftedResult0, liftedResult')
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