module Data.Tagged
(
Tagged(..)
, retag
, untag
, tagSelf
, untagSelf
, asTaggedTypeOf
, Proxy(..)
, reproxy
, asProxyTypeOf
, proxy
, unproxy
) where
import Control.Applicative ((<$>), Applicative(..))
import Control.Monad (liftM)
import Data.Traversable (Traversable(..))
import Data.Foldable (Foldable(..))
import Data.Monoid (Monoid(..))
import Data.Default (Default(..))
import Data.Data (Data,Typeable)
import Data.Ix (Ix)
import Text.Read
newtype Tagged s b = Tagged { unTagged :: b }
deriving (Eq,Ord,Ix,Enum,Bounded,Data,Typeable,Num,Real,Integral,Fractional,Floating,RealFrac,RealFloat)
instance Show b => Show (Tagged s b) where
showsPrec n (Tagged b) = showParen (n > 10) $
showString "Tagged " .
showsPrec 10 b
instance Read b => Read (Tagged s b) where
readPrec = parens $ prec 10 $ do
Ident "Tagged" <- lexP
Tagged <$> step readPrec
instance Functor (Tagged s) where
fmap f (Tagged x) = Tagged (f x)
instance Applicative (Tagged s) where
pure = Tagged
Tagged f <*> Tagged x = Tagged (f x)
instance Monad (Tagged s) where
return = Tagged
Tagged m >>= k = k m
_ >> n = n
instance Foldable (Tagged s) where
foldMap f (Tagged x) = f x
fold (Tagged x) = x
foldr f z (Tagged x) = f x z
foldl f z (Tagged x) = f z x
foldl1 _ (Tagged x) = x
foldr1 _ (Tagged x) = x
instance Traversable (Tagged s) where
traverse f (Tagged x) = Tagged <$> f x
sequenceA (Tagged x) = Tagged <$> x
mapM f (Tagged x) = liftM Tagged (f x)
sequence (Tagged x) = liftM Tagged x
retag :: Tagged s b -> Tagged t b
retag = Tagged . unTagged
untag :: Tagged s b -> b
untag = unTagged
tagSelf :: a -> Tagged a a
tagSelf = Tagged
asTaggedTypeOf :: s -> Tagged s b -> s
asTaggedTypeOf = const
untagSelf :: Tagged a a -> a
untagSelf (Tagged x) = x
data Proxy p = Proxy
instance Enum (Proxy s) where
succ _ = error "Proxy.succ"
pred _ = error "Proxy.pred"
fromEnum _ = 0
toEnum 0 = Proxy
toEnum _ = error "Proxy.toEnum: 0 expected"
enumFrom _ = [Proxy]
enumFromThen _ _ = [Proxy]
enumFromThenTo _ _ _ = [Proxy]
enumFromTo _ _ = [Proxy]
instance Bounded (Proxy s) where
minBound = Proxy
maxBound = Proxy
instance Functor Proxy where
fmap _ _ = Proxy
instance Applicative Proxy where
pure _ = Proxy
_ <*> _ = Proxy
instance Monoid (Proxy s) where
mempty = Proxy
mappend _ _ = Proxy
mconcat _ = Proxy
instance Monad Proxy where
return _ = Proxy
_ >>= _ = Proxy
instance Foldable Proxy where
foldMap _ _ = mempty
fold _ = mempty
foldr _ z _ = z
foldl _ z _ = z
foldl1 _ _ = error "foldl1: Proxy"
foldr1 _ _ = error "foldr1: Proxy"
instance Traversable Proxy where
traverse _ _ = pure Proxy
sequenceA _ = pure Proxy
mapM _ _ = return Proxy
sequence _ = return Proxy
instance Default (Proxy s) where
def = Proxy
reproxy :: Proxy s -> Proxy t
reproxy _ = Proxy
proxy :: Tagged s a -> Proxy s -> a
proxy (Tagged x) _ = x
unproxy :: (Proxy s -> a) -> Tagged s a
unproxy f = Tagged (f Proxy)
asProxyTypeOf :: a -> Proxy a -> a
asProxyTypeOf = const