{-# LANGUAGE TypeOperators, Rank2Types, EmptyDataDecls, MultiParamTypeClasses, FunctionalDependencies, FlexibleContexts, FlexibleInstances, UndecidableInstances, IncoherentInstances, OverlappingInstances #-} module Data.Rope.Branded ( Branded(..) , Unsafe , UBR , null -- :: (s `Branded` Rope) a -> Bool -- * Unpacking Ropes , head -- :: Unpackable t => (s `Branded` Rope) a -> t , last -- :: Unpackable t => (s `Branded` Rope) a -> t , unpack -- :: Unpackable t => (s `Branded` Rope) a -> [t] -- * MonadWriter , runBranded , execBranded -- MonadWriter terminology for 'context' ) where import Prelude hiding (null, head, last, take, drop, span, break, splitAt, takeWhile, dropWhile) import Control.Applicative hiding (empty) import Control.Monad.Writer.Class import Data.Rope.Branded.Comonad import Data.Monoid import Data.FingerTree (Measured(..)) import Data.Foldable (Foldable) import qualified Data.Foldable import Data.Traversable (Traversable(traverse)) import qualified Data.Rope.Internal as Rope import Data.Rope.Internal (Rope(..),Unpackable) type UBR a = (Unsafe `Branded` Rope) a data Unsafe data Branded brand t a = Branded { context :: !t, extractBranded :: a } null :: Branded s Rope a -> Bool null = Rope.null . context {-# INLINE null #-} head :: Unpackable t => Branded s Rope a -> t head = Rope.head . context {-# INLINE head #-} last :: Unpackable t => Branded s Rope a -> t last = Rope.last . context {-# INLINE last #-} unpack :: Unpackable t => Branded s Rope a -> [t] unpack (Branded s _) = Rope.unpack s {-# INLINE unpack #-} instance Measured v t => Measured v (Branded s t a) where measure = measure . context instance Functor (Branded s t) where fmap f (Branded s a) = Branded s (f a) instance Comonad (Branded s t) where extract = extractBranded extend f a@(Branded s _) = Branded s (f a) duplicate a@(Branded s _) = Branded s a instance Foldable (Branded s t) where foldr f z (Branded _ a) = f a z foldr1 _ (Branded _ a) = a foldl f z (Branded _ a) = f z a foldl1 _ (Branded _ a) = a foldMap f (Branded _ a) = f a instance Traversable (Branded s t) where traverse f (Branded s a) = Branded s <$> f a instance Monoid t => Applicative (Branded Unsafe t) where pure = Branded mempty Branded s f <*> Branded s' a = Branded (s `mappend` s') (f a) instance Monoid t => Monad (Branded Unsafe t) where return = Branded mempty Branded s a >>= f = Branded (s `mappend` s') b where Branded s' b = f a instance (Monoid t, Monoid m) => Monoid (Branded Unsafe t m) where mempty = Branded mempty mempty Branded r t `mappend` Branded s u = Branded (r `mappend` s) (t `mappend` u) -- > sample :: Branded Unsafe Rope () -- > sample = do pack "Hello" -- > pack ' ' -- > pack "World" -- > instance Monoid t => MonadWriter t (Branded Unsafe t) where tell t = Branded t () listen (Branded t a) = Branded t (a, t) pass (Branded t (a,f)) = Branded (f t) a runBranded :: Branded s t a -> (a, t) runBranded (Branded t a) = (a, t) {-# INLINE runBranded #-} execBranded :: Branded s t a -> t execBranded (Branded t _) = t {-# INLINE execBranded #-}