Data.Tagged

tagged-0.8.4: Haskell 98 phantom types to avoid unsafely passing dummy arguments

Copyright | 2009-2015 Edward Kmett
License | BSD3
Maintainer | Edward Kmett <ekmett@gmail.com>
Stability | experimental
Portability | portable
Safe Haskell | Safe
Language | Haskell98

Data.Tagged

Contents

- Tagged values
- Conversion
- Proxy methods GHC dropped

Description

Synopsis

- newtype Tagged s b = Tagged {
  - unTagged :: b
  }
- retag :: Tagged s b -> Tagged t b
- untag :: Tagged s b -> b
- tagSelf :: a -> Tagged a a
- untagSelf :: Tagged a a -> a
- asTaggedTypeOf :: s -> tagged s b -> s
- witness :: Tagged a b -> a -> b
- proxy :: Tagged s a -> proxy s -> a
- unproxy :: (Proxy s -> a) -> Tagged s a
- tagWith :: proxy s -> a -> Tagged s a
- reproxy :: proxy a -> Proxy b

# Tagged values

newtype Tagged s b

A ``Tagged` s b` value is a value `b` with an attached phantom type `s`. This can be used in place of the more traditional but less safe idiom of passing in an undefined value with the type, because unlike an `(s -> b)`, a ``Tagged` s b` can't try to use the argument `s` as a real value.

Moreover, you don't have to rely on the compiler to inline away the extra argument, because the newtype is "free"

`Tagged` has kind `k -> * -> *` if the compiler supports `PolyKinds`, therefore there is an extra `k` showing in the instance haddocks that may cause confusion.

Constructors

Tagged |
Fields unTagged :: b

Instances

Bifunctor (Tagged *) |
Monad (Tagged k s) |
Functor (Tagged k s) |
Applicative (Tagged k s) |
Foldable (Tagged k s) |
Traversable (Tagged k s) |
Generic1 (Tagged k s) |
Bounded b => Bounded (Tagged k s b) |
Enum a => Enum (Tagged k s a) |
Eq b => Eq (Tagged k s b) |
Floating a => Floating (Tagged k s a) |
Fractional a => Fractional (Tagged k s a) |
Integral a => Integral (Tagged k s a) |
(Data s, Data b) => Data (Tagged * s b) |
Num a => Num (Tagged k s a) |
Ord b => Ord (Tagged k s b) |
Read b => Read (Tagged k s b) |
Real a => Real (Tagged k s a) |
RealFloat a => RealFloat (Tagged k s a) |
RealFrac a => RealFrac (Tagged k s a) |
Show b => Show (Tagged k s b) |
Ix b => Ix (Tagged k s b) |
IsString a => IsString (Tagged k s a) |
Generic (Tagged k s b) |
Storable a => Storable (Tagged k s a) |
Bits a => Bits (Tagged k s a) |
FiniteBits a => FiniteBits (Tagged k s a) |
Monoid a => Monoid (Tagged k s a) |
NFData b => NFData (Tagged k s b) |
type Rep1 (Tagged k s) |
type Rep (Tagged k s b) |

retag :: Tagged s b -> Tagged t b

Some times you need to change the tag you have lying around. Idiomatic usage is to make a new combinator for the relationship between the tags that you want to enforce, and define that combinator using `retag`.

    data Succ n
    retagSucc :: Tagged n a -> Tagged (Succ n) a
    retagSucc = retag

untag :: Tagged s b -> b

Alias for `unTagged`

tagSelf :: a -> Tagged a a

Tag a value with its own type.

untagSelf :: Tagged a a -> a

`untagSelf` is a type-restricted version of `untag`.

asTaggedTypeOf :: s -> tagged s b -> s

`asTaggedTypeOf` is a type-restricted version of `const`. It is usually used as an infix operator, and its typing forces its first argument (which is usually overloaded) to have the same type as the tag of the second.

witness :: Tagged a b -> a -> b

# Conversion

proxy :: Tagged s a -> proxy s -> a

Convert from a `Tagged` representation to a representation based on a `Proxy`.

unproxy :: (Proxy s -> a) -> Tagged s a

Convert from a representation based on a `Proxy` to a `Tagged` representation.

tagWith :: proxy s -> a -> Tagged s a

Another way to convert a proxy to a tag.

# Proxy methods GHC dropped

reproxy :: proxy a -> Proxy b

Some times you need to change the proxy you have lying around. Idiomatic usage is to make a new combinator for the relationship between the proxies that you want to enforce, and define that combinator using `reproxy`.

    data Succ n
    reproxySucc :: proxy n -> Proxy (Succ n)
    reproxySucc = reproxy