#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 708
#endif
module Control.Reference.Predefined where
import Control.Reference.Representation
import Control.Applicative
import Control.Monad
import qualified Data.Traversable as Trav
import Control.Monad.Trans.Control
import Control.Monad.Identity
import Control.Monad.Writer
import Control.Monad.State
import Control.Concurrent.MVar.Lifted
import Control.Concurrent.Chan
import Data.IORef
import Data.Map as Map
import Data.Either.Combinators
self :: Lens a b a b
self = reference return (const . return) id
emptyRef :: Simple RefPlus s a
emptyRef = reference (const mzero) (const return) (const return)
traverse :: (Trav.Traversable t) => Traversal (t a) (t b) a b
traverse = reference (morph . execWriter . Trav.mapM (tell . (:[])))
(Trav.mapM . const . return)
Trav.mapM
iso :: (a -> b) -> (b -> a) -> Lens a a b b
iso f g = reference (return . f) (\b _ -> return . g $ b) (\trf a -> trf (f a) >>= return . g )
lens :: (s -> a) -> (b -> s -> t) -> Lens s t a b
lens get set = reference (return . get)
(\b -> return . set b )
(\f a -> f (get a) >>= \b -> return $ set b a)
partial :: (s -> Either t (a, b -> t)) -> Partial s t a b
partial access
= reference
(\s -> case access s of Left _ -> morph Nothing
Right (a,_) -> return a)
(\b s -> case access s of Left t -> return t
Right (_,set) -> return (set b))
(\f s -> case access s of Left t -> return t
Right (a,set) -> f a >>= return . set)
simplePartial :: (s -> Maybe (a, a -> s)) -> Partial s s a a
simplePartial access
= partial (\s -> case access s of Just x -> Right x
Nothing -> Left s)
fromLens :: (forall f . Functor f => (a -> f b) -> s -> f t) -> Lens s t a b
fromLens l = reference (\s -> return (getConst $ l Const s))
(\b -> return . (runIdentity . l (\_ -> Identity b)))
l
fromTraversal :: (forall f . Applicative f => (a -> f b) -> s -> f t) -> Traversal s t a b
fromTraversal l = reference (morph . execWriter . l (\a -> tell [a] >> return undefined))
(\b -> return . (runIdentity . l (\_ -> Identity b)))
l
filtered :: (a -> Bool) -> Simple RefPlus a a
filtered p = reference (\s -> if p s then return s else mzero)
(\a s -> if p s then return a else return s)
(\f s -> if p s then f s else return s)
just :: Partial (Maybe a) (Maybe b) a b
just = partial (\case Just x -> Right (x, Just)
Nothing -> Left Nothing)
right :: Partial (Either a b) (Either a c) b c
right = partial (\case Right x -> Right (x, Right)
Left a -> Left (Left a))
left :: Partial (Either a c) (Either b c) a b
left = partial (\case Left a -> Right (a, Left)
Right r -> Left (Right r))
anyway :: Lens (Either a a) (Either b b) a b
anyway = reference (either return return)
(\b -> return . mapBoth (const b) (const b))
(\f -> either (f >=> return . Left) (f >=> return . Right))
both :: Traversal (a,a) (b,b) a b
both = reference (\(x,y) -> morph [x,y])
(\v -> return . const (v,v))
(\f (x,y) -> (,) <$> f x <*> f y)
_head :: Simple Partial [a] a
_head = simplePartial (\case [] -> Nothing; x:xs -> Just (x,(:xs)))
_tail :: Simple Partial [a] [a]
_tail = simplePartial (\case [] -> Nothing; x:xs -> Just (xs,(x:)))
class Association e where
type AssocIndex e :: *
type AssocElem e :: *
element :: AssocIndex e -> Simple Partial e (AssocElem e)
instance Association [a] where
type AssocIndex [a] = Int
type AssocElem [a] = a
element i = reference (morph . at i) (\v -> upd (const (return v)))
upd
where at :: Int -> [a] -> Maybe a
at n _ | n < 0 = Nothing
at _ [] = Nothing
at 0 (x:_) = Just x
at n (_:xs) = at (n1) xs
upd :: Monad w => (a -> w a) -> [a] -> w [a]
upd f ls = let (before,rest) = splitAt i ls
in case rest of [] -> return before
(x:xs) -> f x >>= \fx -> return $ before ++ fx : xs
instance Ord k => Association (Map k v) where
type AssocIndex (Map k v) = k
type AssocElem (Map k v) = v
element k = reference (morph . Map.lookup k)
(\v -> return . insert k v)
(\trf m -> case Map.lookup k m of Just x -> trf x >>= \x' -> return (insert k x' m)
Nothing -> return m)
data Console = Console
consoleLine :: Simple IOLens Console String
consoleLine
= reference (const (morph getLine))
(\str -> const (morph (putStrLn str) >> return Console))
(\f -> const (morph getLine >>= f
>>= morph . putStrLn
>> return Console))
mvar :: ( Functor w, Applicative w, Monad w, MMorph IO w, MonadBaseControl IO w
, Functor r, Applicative r, Monad r, MMorph IO r)
=> Simple (Reference w r) (MVar a) a
mvar = reference (morph . (readMVar :: MVar a -> IO a))
(\newVal mv -> do empty <- isEmptyMVar mv
when empty (swapMVar mv newVal >> return ())
return mv)
(\trf mv -> modifyMVarMasked_ mv trf >> return mv)
chan :: Simple IOLens (Chan a) a
chan = reference (morph . readChan)
(\a ch -> morph (writeChan ch a) >> return ch)
(\trf ch -> morph (readChan ch) >>= trf
>>= morph . writeChan ch >> return ch)
ioref :: Simple IOLens (IORef a) a
ioref = reference (morph . readIORef)
(\v ior -> morph (atomicWriteIORef ior v) >> return ior)
(\trf ior -> morph (readIORef ior)
>>= trf >>= morph . writeIORef ior >> return ior)
state :: forall s m a . Monad m => Simple (StateLens s m) a s
state = reference (morph . const get') (\a s -> morph (put' a) >> return s)
(\trf s -> (morph get' >>= trf >> return s))
where put' = put :: s -> StateT s m ()
get' = get :: StateT s m s