tagged-0.8.2: 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 Source

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 *) Source |
Monad (Tagged k s) Source |
Functor (Tagged k s) Source |
Applicative (Tagged k s) Source |
Foldable (Tagged k s) Source |
Traversable (Tagged k s) Source |
Generic1 (Tagged k s) Source |
Bounded b => Bounded (Tagged k s b) Source |
Enum a => Enum (Tagged k s a) Source |
Eq b => Eq (Tagged k s b) Source |
Floating a => Floating (Tagged k s a) Source |
Fractional a => Fractional (Tagged k s a) Source |
Integral a => Integral (Tagged k s a) Source |
(Data s, Data b) => Data (Tagged * s b) Source |
Num a => Num (Tagged k s a) Source |
Ord b => Ord (Tagged k s b) Source |
Read b => Read (Tagged k s b) Source |
Real a => Real (Tagged k s a) Source |
RealFloat a => RealFloat (Tagged k s a) Source |
RealFrac a => RealFrac (Tagged k s a) Source |
Show b => Show (Tagged k s b) Source |
Ix b => Ix (Tagged k s b) Source |
Generic (Tagged k s b) Source |
Monoid a => Monoid (Tagged k s a) Source |
NFData b => NFData (Tagged k s b) Source |
type Rep1 (Tagged k s) Source |
type Rep (Tagged k s b) Source |

retag :: Tagged s b -> Tagged t b Source

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 Source

Alias for `unTagged`

tagSelf :: a -> Tagged a a Source

Tag a value with its own type.

untagSelf :: Tagged a a -> a Source

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

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

`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 Source

# Conversion

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

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

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

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

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

Another way to convert a proxy to a tag.

# Proxy methods GHC dropped

reproxy :: proxy a -> Proxy b Source

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