@@ -1,6 +1,10 @@
1−{- | This module provides a pure implementation of Reflex, which is intended to serve as a reference for the semantics of the Reflex class. All implementations of Reflex should produce the same results as this implementation, although performance and laziness/strictness may differ.
1+{- | This module provides a pure implementation of Reflex, which is intended
2+to serve as a reference for the semantics of the Reflex class. All implementations
3+of Reflex should produce the same results as this implementation, although performance
4+and laziness/strictness may differ.
25-}
3−{-# LANGUAGE TypeFamilies, MultiParamTypeClasses, EmptyDataDecls #-}
6+
7+{-# LANGUAGE TypeFamilies, MultiParamTypeClasses, EmptyDataDecls, InstanceSigs #-}
48module Reflex.Pure where
59
610import Reflex.Class
@@ -8,39 +12,65 @@ import Data.Functor.Misc
812
913import Control.Monad
1014import Data.MemoTrie
15+import Data.Dependent.Map (DMap, GCompare)
1116import qualified Data.Dependent.Map as DMap
1217
1318data Pure t
1419
15−-- | The Enum instance of t must be dense: for all x :: t, there must not exist any y :: t such that pred x < y < x
16−-- The HasTrie instance will be used exclusively to memoize functions of t, not for any of its other capabilities
20+-- | The Enum instance of t must be dense: for all x :: t, there must not exist
21+-- any y :: t such that pred x < y < x. The HasTrie instance will be used exclusively
22+-- to memoize functions of t, not for any of its other capabilities.
1723instance (Enum t, HasTrie t, Ord t) => Reflex (Pure t) where
24+
1825 newtype Behavior (Pure t) a = Behavior { unBehavior :: t -> a }
19− newtype Event (Pure t) a = Event { unEvent :: t -> Maybe a }
26+ newtype Event (Pure t) a = Event { unEvent :: t -> Maybe a }
27+
2028 type PushM (Pure t) = (->) t
2129 type PullM (Pure t) = (->) t
30+
31+ never :: Event (Pure t) a
2232 never = Event $ \_ -> Nothing
33+
34+ constant :: a -> Behavior (Pure t) a
2335 constant x = Behavior $ \_ -> x
36+
37+ push :: (a -> PushM (Pure t) (Maybe b)) -> Event (Pure t) a -> Event (Pure t) b
2438 push f e = Event $ memo $ \t -> unEvent e t >>= \o -> f o t
39+
40+ pull :: PullM (Pure t) a -> Behavior (Pure t) a
2541 pull = Behavior . memo
42+
43+ merge :: GCompare k => DMap (WrapArg (Event (Pure t)) k) -> Event (Pure t) (DMap k)
2644 merge events = Event $ memo $ \t ->
2745 let currentOccurrences = unwrapDMapMaybe (($ t) . unEvent) events
2846 in if DMap.null currentOccurrences
2947 then Nothing
3048 else Just currentOccurrences
49+
50+ fan :: GCompare k => Event (Pure t) (DMap k) -> EventSelector (Pure t) k
3151 fan e = EventSelector $ \k -> Event $ \t -> unEvent e t >>= DMap.lookup k
52+
53+ switch :: Behavior (Pure t) (Event (Pure t) a) -> Event (Pure t) a
3254 switch b = Event $ memo $ \t -> unEvent (unBehavior b t) t
55+
56+ coincidence :: Event (Pure t) (Event (Pure t) a) -> Event (Pure t) a
3357 coincidence e = Event $ memo $ \t -> unEvent e t >>= \o -> unEvent o t
3458
3559instance Ord t => MonadSample (Pure t) ((->) t) where
60+
61+ sample :: Behavior (Pure t) a -> (t -> a)
3662 sample = unBehavior
3763
3864instance (Enum t, HasTrie t, Ord t) => MonadHold (Pure t) ((->) t) where
65+
66+ hold :: a -> Event (Pure t) a -> (t -> (Behavior (Pure t) a))
3967 hold initialValue e initialTime = Behavior f
4068 where f = memo $ \sampleTime ->
41− if sampleTime <= initialTime -- Really, the sampleTime should never be prior to the initialTime, because that would mean the Behavior is being sampled before being created
69+ -- Really, the sampleTime should never be prior to the initialTime,
70+ -- because that would mean the Behavior is being sampled before being created.
71+ if sampleTime <= initialTime
4272 then initialValue
4373 else let lastTime = pred sampleTime
4474 in case unEvent e lastTime of
4575 Nothing -> f lastTime
46− Just x -> x
76+ Just x -> x