webgear-core-1.2.0: Composable, type-safe library to build HTTP APIs
Safe HaskellSafe-Inferred
LanguageHaskell2010

WebGear.Core.Trait

Description

Traits are optional attributes associated with a value. For example, a list containing totally ordered values might have a Maximum trait where the associated attribute is the maximum value. This trait exists only if the list is non-empty. The Trait typeclass provides an interface to extract such trait attributes.

Traits help to associate attributes with values in a type-safe manner.

Traits are somewhat similar to refinement types, but allow arbitrary attributes to be associated with a value instead of only a predicate.

A value a associated with traits ts is referred to as a witnessed value, represented by the type a `With` ts where ts is a type-level list. You can extract a trait attribute from a witnessed value with:

pick @t (from witnessedValue)

The above expression will result in a compile-time error if t is not present in the type-level list of the witnessed value's type.

You can create a witnessed value in a number of ways:

First, you can use wzero to lift a regular value to a witnessed value with no associated traits.

Second, you can use probe to search for the presence of a trait and add it to the witnessed value; this will adjust the type-level list accordingly. This is used in cases where the regular value already contains the trait attribute which can be extracted using the Get typeclass.

Third, you can use plant to add a trait attribute to a witnessed value, thereby extending its type-level list with one more trait. This is used in cases where you want to modify the witnessed value. This operation requires an implementation of the Set typeclass.

Synopsis

Core Types

class Trait (t :: Type) a Source #

A trait is an attribute t associated with a value a.

Associated Types

type Attribute t a :: Type Source #

Type of the associated attribute when the trait holds for a value

Instances

Instances details
Trait UnknownContentBody Response Source # 
Instance details

Defined in WebGear.Core.Trait.Body

Trait Method Request Source # 
Instance details

Defined in WebGear.Core.Trait.Method

Associated Types

type Attribute Method Request Source #

Trait Path Request Source # 
Instance details

Defined in WebGear.Core.Trait.Path

Associated Types

type Attribute Path Request Source #

Trait PathEnd Request Source # 
Instance details

Defined in WebGear.Core.Trait.Path

Associated Types

type Attribute PathEnd Request Source #

Trait Status Response Source # 
Instance details

Defined in WebGear.Core.Trait.Status

Associated Types

type Attribute Status Response Source #

Trait (Body mt t) Request Source # 
Instance details

Defined in WebGear.Core.Trait.Body

Associated Types

type Attribute (Body mt t) Request Source #

Trait (Body mt t) Response Source # 
Instance details

Defined in WebGear.Core.Trait.Body

Associated Types

type Attribute (Body mt t) Response Source #

Trait (SetCookie 'Optional name) Response Source # 
Instance details

Defined in WebGear.Core.Trait.Cookie

Associated Types

type Attribute (SetCookie 'Optional name) Response Source #

Trait (SetCookie 'Required name) Response Source # 
Instance details

Defined in WebGear.Core.Trait.Cookie

Associated Types

type Attribute (SetCookie 'Required name) Response Source #

Trait (PathVar tag val) Request Source # 
Instance details

Defined in WebGear.Core.Trait.Path

Associated Types

type Attribute (PathVar tag val) Request Source #

Trait (Cookie 'Optional name val) Request Source # 
Instance details

Defined in WebGear.Core.Trait.Cookie

Associated Types

type Attribute (Cookie 'Optional name val) Request Source #

Trait (Cookie 'Required name val) Request Source # 
Instance details

Defined in WebGear.Core.Trait.Cookie

Associated Types

type Attribute (Cookie 'Required name val) Request Source #

Trait (ResponseHeader 'Optional name val) Response Source # 
Instance details

Defined in WebGear.Core.Trait.Header

Associated Types

type Attribute (ResponseHeader 'Optional name val) Response Source #

Trait (ResponseHeader 'Required name val) Response Source # 
Instance details

Defined in WebGear.Core.Trait.Header

Associated Types

type Attribute (ResponseHeader 'Required name val) Response Source #

Trait (RequestHeader 'Optional 'Lenient name val) Request Source # 
Instance details

Defined in WebGear.Core.Trait.Header

Associated Types

type Attribute (RequestHeader 'Optional 'Lenient name val) Request Source #

Trait (RequestHeader 'Optional 'Strict name val) Request Source # 
Instance details

Defined in WebGear.Core.Trait.Header

Associated Types

type Attribute (RequestHeader 'Optional 'Strict name val) Request Source #

Trait (RequestHeader 'Required 'Lenient name val) Request Source # 
Instance details

Defined in WebGear.Core.Trait.Header

Associated Types

type Attribute (RequestHeader 'Required 'Lenient name val) Request Source #

Trait (RequestHeader 'Required 'Strict name val) Request Source # 
Instance details

Defined in WebGear.Core.Trait.Header

Associated Types

type Attribute (RequestHeader 'Required 'Strict name val) Request Source #

Trait (QueryParam 'Optional 'Lenient name val) Request Source # 
Instance details

Defined in WebGear.Core.Trait.QueryParam

Associated Types

type Attribute (QueryParam 'Optional 'Lenient name val) Request Source #

Trait (QueryParam 'Optional 'Strict name val) Request Source # 
Instance details

Defined in WebGear.Core.Trait.QueryParam

Associated Types

type Attribute (QueryParam 'Optional 'Strict name val) Request Source #

Trait (QueryParam 'Required 'Lenient name val) Request Source # 
Instance details

Defined in WebGear.Core.Trait.QueryParam

Associated Types

type Attribute (QueryParam 'Required 'Lenient name val) Request Source #

Trait (QueryParam 'Required 'Strict name val) Request Source # 
Instance details

Defined in WebGear.Core.Trait.QueryParam

Associated Types

type Attribute (QueryParam 'Required 'Strict name val) Request Source #

Trait (BasicAuth' 'Optional scheme m e a) Request Source # 
Instance details

Defined in WebGear.Core.Trait.Auth.Basic

Associated Types

type Attribute (BasicAuth' 'Optional scheme m e a) Request Source #

Trait (BasicAuth' 'Required scheme m e a) Request Source # 
Instance details

Defined in WebGear.Core.Trait.Auth.Basic

Associated Types

type Attribute (BasicAuth' 'Required scheme m e a) Request Source #

Trait (JWTAuth' 'Optional scheme m e a) Request Source # 
Instance details

Defined in WebGear.Core.Trait.Auth.JWT

Associated Types

type Attribute (JWTAuth' 'Optional scheme m e a) Request Source #

Trait (JWTAuth' 'Required scheme m e a) Request Source # 
Instance details

Defined in WebGear.Core.Trait.Auth.JWT

Associated Types

type Attribute (JWTAuth' 'Required scheme m e a) Request Source #

class Trait t a => TraitAbsence t a Source #

A trait t that can be retrieved from a but could be absent.

Associated Types

type Absence t a :: Type Source #

Type that indicates that the trait does not exist for a value. This could be an error message, exception etc.

Instances

Instances details
TraitAbsence Method Request Source # 
Instance details

Defined in WebGear.Core.Trait.Method

Associated Types

type Absence Method Request Source #

TraitAbsence Path Request Source # 
Instance details

Defined in WebGear.Core.Trait.Path

Associated Types

type Absence Path Request Source #

TraitAbsence PathEnd Request Source # 
Instance details

Defined in WebGear.Core.Trait.Path

Associated Types

type Absence PathEnd Request Source #

TraitAbsence (Body mt t) Request Source # 
Instance details

Defined in WebGear.Core.Trait.Body

Associated Types

type Absence (Body mt t) Request Source #

TraitAbsence (PathVar tag val) Request Source # 
Instance details

Defined in WebGear.Core.Trait.Path

Associated Types

type Absence (PathVar tag val) Request Source #

TraitAbsence (Cookie 'Optional name val) Request Source # 
Instance details

Defined in WebGear.Core.Trait.Cookie

Associated Types

type Absence (Cookie 'Optional name val) Request Source #

TraitAbsence (Cookie 'Required name val) Request Source # 
Instance details

Defined in WebGear.Core.Trait.Cookie

Associated Types

type Absence (Cookie 'Required name val) Request Source #

TraitAbsence (RequestHeader 'Optional 'Lenient name val) Request Source # 
Instance details

Defined in WebGear.Core.Trait.Header

Associated Types

type Absence (RequestHeader 'Optional 'Lenient name val) Request Source #

TraitAbsence (RequestHeader 'Optional 'Strict name val) Request Source # 
Instance details

Defined in WebGear.Core.Trait.Header

Associated Types

type Absence (RequestHeader 'Optional 'Strict name val) Request Source #

TraitAbsence (RequestHeader 'Required 'Lenient name val) Request Source # 
Instance details

Defined in WebGear.Core.Trait.Header

Associated Types

type Absence (RequestHeader 'Required 'Lenient name val) Request Source #

TraitAbsence (RequestHeader 'Required 'Strict name val) Request Source # 
Instance details

Defined in WebGear.Core.Trait.Header

Associated Types

type Absence (RequestHeader 'Required 'Strict name val) Request Source #

TraitAbsence (QueryParam 'Optional 'Lenient name val) Request Source # 
Instance details

Defined in WebGear.Core.Trait.QueryParam

Associated Types

type Absence (QueryParam 'Optional 'Lenient name val) Request Source #

TraitAbsence (QueryParam 'Optional 'Strict name val) Request Source # 
Instance details

Defined in WebGear.Core.Trait.QueryParam

Associated Types

type Absence (QueryParam 'Optional 'Strict name val) Request Source #

TraitAbsence (QueryParam 'Required 'Lenient name val) Request Source # 
Instance details

Defined in WebGear.Core.Trait.QueryParam

Associated Types

type Absence (QueryParam 'Required 'Lenient name val) Request Source #

TraitAbsence (QueryParam 'Required 'Strict name val) Request Source # 
Instance details

Defined in WebGear.Core.Trait.QueryParam

Associated Types

type Absence (QueryParam 'Required 'Strict name val) Request Source #

TraitAbsence (BasicAuth' 'Optional scheme m e a) Request Source # 
Instance details

Defined in WebGear.Core.Trait.Auth.Basic

Associated Types

type Absence (BasicAuth' 'Optional scheme m e a) Request Source #

TraitAbsence (BasicAuth' 'Required scheme m e a) Request Source # 
Instance details

Defined in WebGear.Core.Trait.Auth.Basic

Associated Types

type Absence (BasicAuth' 'Required scheme m e a) Request Source #

TraitAbsence (JWTAuth' 'Optional scheme m e a) Request Source # 
Instance details

Defined in WebGear.Core.Trait.Auth.JWT

Associated Types

type Absence (JWTAuth' 'Optional scheme m e a) Request Source #

TraitAbsence (JWTAuth' 'Required scheme m e a) Request Source # 
Instance details

Defined in WebGear.Core.Trait.Auth.JWT

Associated Types

type Absence (JWTAuth' 'Required scheme m e a) Request Source #

type family Prerequisite (t :: Type) (ts :: [Type]) (a :: Type) :: Constraint Source #

Indicates the constraints a trait depends upon as a prerequisite. This is used to assert that a trait t can be extracted from a value a only if one or more other traits are present in the trait list ts associated with it.

If a trait does not depend on other traits this can be set to the empty contraint ().

Instances

Instances details
type Prerequisite Method ts Request Source # 
Instance details

Defined in WebGear.Core.Trait.Method

type Prerequisite Path ts Request Source # 
Instance details

Defined in WebGear.Core.Trait.Path

type Prerequisite PathEnd ts Request Source # 
Instance details

Defined in WebGear.Core.Trait.Path

type Prerequisite (Body mt t) ts Request Source # 
Instance details

Defined in WebGear.Core.Trait.Body

type Prerequisite (Body mt t) ts Request = ()
type Prerequisite (PathVar tag val) ts Request Source # 
Instance details

Defined in WebGear.Core.Trait.Path

type Prerequisite (PathVar tag val) ts Request = ()
type Prerequisite (Cookie e name val) ts Request Source # 
Instance details

Defined in WebGear.Core.Trait.Cookie

type Prerequisite (Cookie e name val) ts Request = HasTrait (RequestHeader e 'Strict "Cookie" Text) ts
type Prerequisite (RequestHeader e p name val) ts Request Source # 
Instance details

Defined in WebGear.Core.Trait.Header

type Prerequisite (RequestHeader e p name val) ts Request = ()
type Prerequisite (QueryParam e p name val) ts Request Source # 
Instance details

Defined in WebGear.Core.Trait.QueryParam

type Prerequisite (QueryParam e p name val) ts Request = ()
type Prerequisite (BasicAuth' x scheme m e a) ts Request Source # 
Instance details

Defined in WebGear.Core.Trait.Auth.Basic

type Prerequisite (BasicAuth' x scheme m e a) ts Request = HasTrait (AuthorizationHeader scheme) ts
type Prerequisite (JWTAuth' x scheme m e a) ts Request Source # 
Instance details

Defined in WebGear.Core.Trait.Auth.JWT

type Prerequisite (JWTAuth' x scheme m e a) ts Request = HasTrait (AuthorizationHeader scheme) ts

class (Arrow h, TraitAbsence t a) => Get h t a where Source #

Extract trait attributes from a value.

Methods

getTrait Source #

Arguments

:: Prerequisite t ts a 
=> t

The trait to witness

-> h (a `With` ts) (Either (Absence t a) (Attribute t a))

Arrow that attemtps to witness the trait and can possibly fail

Attempt to witness the trait attribute from the value a.

type family Gets h ts a :: Constraint where ... Source #

Gets h ts a is equivalent to (Get h t1 a, Get h t2 a, ..., Get h tn a) where ts = [t1, t2, ..., tn].

Equations

Gets h '[] a = () 
Gets h (t : ts) a = (Get h t a, Gets h ts a) 

class (Arrow h, Trait t a) => Set h (t :: Type) a where Source #

Associate a trait attribute on a value

Methods

setTrait Source #

Arguments

:: t

The trait to set

-> ((a `With` ts) -> a -> Attribute t a -> a `With` (t : ts))

A function to generate a witnessed value. This function must be called by the setTrait implementation to generate a witnessed value.

-> h (a `With` ts, Attribute t a) (a `With` (t : ts))

An arrow that attaches a new trait attribute to a witnessed value.

Set a trait attribute t on the value a `With` ts.

type family Sets h ts a :: Constraint where ... Source #

Sets h ts a is equivalent to (Set h t1 a, Set h t2 a, ..., Set h tn a) where ts = [t1, t2, ..., tn].

Equations

Sets h '[] a = () 
Sets h (t : ts) a = (Set h t a, Sets h ts a) 

data With a (ts :: [Type]) Source #

A value associated with a list of traits, referred to as a witnessed value. Typically, this is used as an infix type constructor:

a `With` ts

where a is a value and ts is a list of traits associated with that value.

If t is a type present in the list of types ts, it is possible to extract its attribute from a witnessed value:

let witnessedValue :: a `With` ts
    witnessedValue = ...

let attr :: Attribute t a
    attr = pick @t (from witnessedValue)

Associating values with attributes

wzero :: a -> a `With` '[] Source #

Lift a value to a witnessed value having no associated traits.

wminus :: (a `With` (t : ts)) -> a `With` ts Source #

Forget the head trait

unwitness :: With a ts -> a Source #

Retrieve the value

probe :: forall t ts h a. (Get h t a, Prerequisite t ts a) => t -> h (a `With` ts) (Either (Absence t a) (a `With` (t : ts))) Source #

Attempt to witness an additional trait with a witnessed value. This can fail indicating an Absence of the trait.

plant :: forall t ts h a. Set h t a => t -> h (a `With` ts, Attribute t a) (a `With` (t : ts)) Source #

Set a trait attribute on witnessed value to produce another witnessed value with the additional trait attached to it.

Retrieve trait attributes from witnessed values

class HasTrait t ts where Source #

Constraint that proves that the trait t is present in the list of traits ts.

Methods

from :: (a `With` ts) -> Tagged t (Attribute t a) Source #

Get the attribute associated with t from a witnessed value. See also: pick.

Instances

Instances details
(TypeError (MissingTrait t) :: Constraint) => HasTrait t ('[] :: [Type]) Source # 
Instance details

Defined in WebGear.Core.Trait

Methods

from :: With a '[] -> Tagged t (Attribute t a) Source #

HasTrait t (t ': ts) Source # 
Instance details

Defined in WebGear.Core.Trait

Methods

from :: With a (t ': ts) -> Tagged t (Attribute t a) Source #

HasTrait t ts => HasTrait t (t' ': ts) Source # 
Instance details

Defined in WebGear.Core.Trait

Methods

from :: With a (t' ': ts) -> Tagged t (Attribute t a) Source #

type family HaveTraits ts qs :: Constraint where ... Source #

Constraint that proves that all the traits in the list ts are also present in the list qs.

Equations

HaveTraits '[] qs = () 
HaveTraits (t : ts) qs = (HasTrait t qs, HaveTraits ts qs) 

pick :: Tagged t a -> a Source #

Retrieve a trait.

pick is used along with from to retrieve an attribute from a witnessed value:

pick @t (from val)

type MissingTrait t = ((((((((Text "The value doesn't have the \8216" :<>: ShowType t) :<>: Text "\8217 trait.") :$$: Text "") :$$: Text "Did you forget to apply an appropriate middleware?") :$$: Text "For e.g. The trait \8216Body JSON t\8217 requires \8216requestBody @t JSON\8217 middleware.") :$$: Text "") :$$: Text "or did you use a wrong trait type?") :$$: Text "For e.g., \8216RequiredQueryParam \"foo\" Int\8217 instead of \8216RequiredQueryParam \"foo\" String\8217?") :$$: Text "" Source #

Type error for nicer UX of missing traits