{-# LANGUAGE Rank2Types #-}
-- | Apply lenses onto Reactive Values, produced RVs that focus
-- only on a part of the value.
--
-- Copyright : (C) Keera Studios Ltd, 2013
-- License : BSD3
-- Maintainer : support@keera.co.uk
module Data.ReactiveLens where
import Control.Lens
import Data.ReactiveValue
-- | Apply a lens to a reactive value, produced another reactive value that
-- focuses on a part of the first.
reactiveFromLens :: (Monad m, Functor m)
=> ReactiveFieldReadWrite m a
-> Lens' a b
-> ReactiveFieldReadWrite m b
reactiveFromLens rv@(ReactiveFieldReadWrite _setter getter notifier) l =
ReactiveFieldReadWrite setter' getter' notifier
where setter' v = reactiveValueModify rv (set l v)
getter' = fmap (view l) getter
-- I'd love to write this, but it's not possible because Haskell does not
-- allow partially applied type synonyms anywhere.
-- instance Monad m => GFunctor (ReactiveFieldReadWrite m) Lens' where
-- gmap = reactiveFromLens
-- | An infix version of 'reactiveFromLense'.
--
-- DUE to a strange problem with GHC-7.10, I cannot use the following
-- equivalente definition: 'flip' 'reactiveFromLens'.
(<$$$>) :: (Monad m, Functor m)
=> Lens' a b -> ReactiveFieldReadWrite m a -> ReactiveFieldReadWrite m b
(<$$$>) l rv@(ReactiveFieldReadWrite _setter getter notifier) =
ReactiveFieldReadWrite setter' getter' notifier
where setter' v = reactiveValueModify rv (set l v)
getter' = fmap (view l) getter
-- I think this bit would need monadic lenses
-- reactiveLens :: Lens' a b -> Lens' (ReactiveFieldReadWrite m a) (ReactiveFieldReadWrite m b)
-- reactiveLens = undefined