module Lens.Micro.Mtl ( view, use, (.=), (%=), (+=), (-=), (*=), (//=), ) where import Control.Applicative import Control.Monad.Reader import Control.Monad.Writer import Control.Monad.State import Lens.Micro import Lens.Micro.Extras {- | 'view' is a synonym for ('^.'), generalised for 'MonadReader' (since functions are instances of the 'MonadReader' class). >>> view _1 (1, 2) 1 It's often used when dealing with environment, for instance: @ doSomething :: ('MonadReader' Config m) => m Int doSomething = do thingy <- 'view' setting1 -- same as “'asks' (^. setting1)” anotherThingy <- 'view' setting2 ... @ -} view :: MonadReader s m => Getting a s a -> m a view l = asks (getConst . l Const) {-# INLINE view #-} {- | 'use' is 'view' which implicitly operates on the state. @ 'use' l = 'gets' ('view' l) @ -} use :: MonadState s m => Getting a s a -> m a use l = gets (view l) {-# INLINE use #-} infix 4 .=, %= infix 4 +=, -=, *=, //= {- | Assign value to the target. This is '.~' which works in 'State'. @ l '.=' b = 'modify' (l '.~' b) @ -} (.=) :: MonadState s m => ASetter s s a b -> b -> m () l .= b = modify (l .~ b) {-# INLINE (.=) #-} {- | Apply a function to the target. This is '%~' which works in 'State'. >>> execState (do _1 %= (+1); _2 %= reverse) (1,"hello") (2,"olleh") -} (%=) :: (MonadState s m) => ASetter s s a b -> (a -> b) -> m () l %= f = modify (l %~ f) {-# INLINE (%=) #-} {- | Add a number to the target. @ l '+=' x = l '%=' (+x) @ -} (+=) :: (MonadState s m, Num a) => ASetter s s a a -> a -> m () l += b = modify (l +~ b) {-# INLINE (+=) #-} {- | Subtract a number from the target. @ l '-=' x = l '%=' ('subtract' x) @ -} (-=) :: (MonadState s m, Num a) => ASetter s s a a -> a -> m () l -= b = modify (l -~ b) {-# INLINE (-=) #-} {- | Multiply the target by a number. @ l '*=' x = l '%=' (*x) @ -} (*=) :: (MonadState s m, Num a) => ASetter s s a a -> a -> m () l *= b = modify (l *~ b) {-# INLINE (*=) #-} {- | Divide the target by a number. @ l //= x = l %= (/x) @ -} (//=) :: (MonadState s m, Fractional a) => ASetter s s a a -> a -> m () l //= a = modify (l //~ a) {-# INLINE (//=) #-}