{-# LANGUAGE GADTs #-} {-# LANGUAGE LambdaCase #-} {-| Tweakable expressions can be updated incrementally. This module exports the central expression type for incremental computations. However, the 'Tweakable' expressions are meant to be created with 'Maker'. Use 'readCache' to retrieve the value of an 'Tweakable' at anytime. -} module Control.Tweak.Tweakable ( -- * The Main Expression Type Tweakable (..) -- * Accessors , getVar , getAnyVar , readCache , readCacheSTM ) where import Control.Concurrent.STM import Control.Tweak.Var import Control.Lens hiding (children, to, from) -- | An expression that can be incrementally updated. -- 'Tweakable' is basically an simple 'Applicative' -- with a cached value. data Tweakable a where App :: Var b -> Tweakable (a -> b) -> Tweakable a -> Tweakable b Pure :: Var a -> Tweakable a -- | Get the cache i.e. the 'Var' from the Tweakable getVar :: Tweakable a -> Var a getVar = \case Pure x -> x App x _ _ -> x -- | Get the cache and put in an 'AnyVar' existential wrapper getAnyVar :: Tweakable a -> AnyVar getAnyVar = AnyVar . getVar instance Cacheable (Tweakable a) where children = lens to from where to = \case Pure c -> view children c App c _ _ -> view children c from x y = case x of Pure c -> Pure (set children y c) App c a b -> App (set children y c) a b -- | Read the cache of a 'Tweakable'. This is nothing more than -- -- @ -- readCache = atomically . readCacheSTM -- @ readCache :: Tweakable a -> IO a readCache = atomically . readCacheSTM -- | Read the cache of a 'Tweakable'. See 'readCache' for an IO version. readCacheSTM :: Tweakable a -> STM a readCacheSTM = readTVar . view output . getVar