data-diverse-4.7.1.0: Extensible records and polymorphic variants.
Safe HaskellNone
LanguageHaskell2010

Data.Diverse.Which.Internal

Synopsis

Which type

data Which (xs :: [Type]) Source #

A Which is an anonymous sum type (also known as a polymorphic variant, or co-record) which can only contain one of the types in the typelist. This is essentially a typed version of Dynamic.

The following functions are available can be used to manipulate unique types in the typelist

These functions are type specified. This means labels are not required because the types themselves can be used to access the Which. It is a compile error to use those functions for duplicate fields.

For duplicate types in the list of possible types, Nat-indexed version of the functions are available:

Encoding: The variant contains a value whose type is at the given position in the type list. This is the same encoding as Haskus.Util.Variant and Data.Hlist.Variant.

The constructor is only exported in the Data.Diverse.Which.Internal module

Constructors

Which !Int Any 

Instances

Instances details
ATraversable Which c m ('[] :: [Type]) Source # 
Instance details

Defined in Data.Diverse.Which.Internal

Methods

atraverse :: forall (xs' :: [Type]). (Applicative m, IsTraversalCase c, xs' ~ TraverseResults c m '[]) => c m '[] -> Which '[] -> m (Which xs') Source #

(Reiterate (c m) (a ': as), ATraversable Which c m as, Case (c m) (a ': as)) => ATraversable Which c m (a ': as) Source # 
Instance details

Defined in Data.Diverse.Which.Internal

Methods

atraverse :: forall (xs' :: [Type]). (Applicative m, IsTraversalCase c, xs' ~ TraverseResults c m (a ': as)) => c m (a ': as) -> Which (a ': as) -> m (Which xs') Source #

AFunctor Which c ('[] :: [Type]) Source #

Terminating AFunctor instance for empty type list

Instance details

Defined in Data.Diverse.Which.Internal

Methods

afmap :: c '[] -> Which '[] -> Which (CaseResults c '[]) Source #

(Reiterate c (a ': as), AFunctor Which c as, Case c (a ': as)) => AFunctor Which c (a ': as) Source #

Recursive AFunctor instance for non empty type list delegate afmap'ing the remainder to an instance of Collector' with one less type in the type list

Instance details

Defined in Data.Diverse.Which.Internal

Methods

afmap :: c (a ': as) -> Which (a ': as) -> Which (CaseResults c (a ': as)) Source #

Semigroup (Which ('[] :: [Type])) Source # 
Instance details

Defined in Data.Diverse.Which.Internal

Methods

(<>) :: Which '[] -> Which '[] -> Which '[]

sconcat :: NonEmpty (Which '[]) -> Which '[]

stimes :: Integral b => b -> Which '[] -> Which '[]

Generic (Which (x ': (x' ': xs))) Source #

A Generic instance encoded as either the x value (:+:) or the diversify0ed remaining 'Which xs'. The C1 and S1 metadata are not encoded.

Instance details

Defined in Data.Diverse.Which.Internal

Associated Types

type Rep (Which (x ': (x' ': xs))) :: Type -> Type

Methods

from :: Which (x ': (x' ': xs)) -> Rep (Which (x ': (x' ': xs))) x0

to :: Rep (Which (x ': (x' ': xs))) x0 -> Which (x ': (x' ': xs))

Generic (Which '[x]) Source #

A terminating Generic instance for one type encoded with pick'. The C1 and S1 metadata are not encoded.

Instance details

Defined in Data.Diverse.Which.Internal

Associated Types

type Rep (Which '[x]) :: Type -> Type

Methods

from :: Which '[x] -> Rep (Which '[x]) x0

to :: Rep (Which '[x]) x0 -> Which '[x]

Generic (Which ('[] :: [Type])) Source #

A terminating Generic instance for no types encoded as a 'Which '[]'. The C1 and S1 metadata are not encoded.

Instance details

Defined in Data.Diverse.Which.Internal

Associated Types

type Rep (Which '[]) :: Type -> Type

Methods

from :: Which '[] -> Rep (Which '[]) x

to :: Rep (Which '[]) x -> Which '[]

WhichRead (Which (x ': xs)) => Read (Which (x ': xs)) Source #

This Read instance tries to read using the each type in the typelist, using the first successful type read.

Instance details

Defined in Data.Diverse.Which.Internal

Methods

readsPrec :: Int -> ReadS (Which (x ': xs))

readList :: ReadS [Which (x ': xs)]

readPrec :: ReadPrec (Which (x ': xs))

readListPrec :: ReadPrec [Which (x ': xs)]

Switch (CaseShowWhich :: Type -> [Type] -> TYPE LiftedRep) ShowS (x ': xs) => Show (Which (x ': xs)) Source #
show (pick' 'A') == "pick 'A'"
Instance details

Defined in Data.Diverse.Which.Internal

Methods

showsPrec :: Int -> Which (x ': xs) -> ShowS

show :: Which (x ': xs) -> String

showList :: [Which (x ': xs)] -> ShowS

Show (Which ('[] :: [Type])) Source # 
Instance details

Defined in Data.Diverse.Which.Internal

Methods

showsPrec :: Int -> Which '[] -> ShowS

show :: Which '[] -> String

showList :: [Which '[]] -> ShowS

Reduce (Which (x ': xs)) (Switcher (CaseFunc NFData) () (x ': xs)) => NFData (Which (x ': xs)) Source # 
Instance details

Defined in Data.Diverse.Which.Internal

Methods

rnf :: Which (x ': xs) -> ()

NFData (Which ('[] :: [Type])) Source # 
Instance details

Defined in Data.Diverse.Which.Internal

Methods

rnf :: Which '[] -> ()

Switch (CaseEqWhich :: Type -> [Type] -> Type) Bool (x ': xs) => Eq (Which (x ': xs)) Source #

Two Whiches are only equal iff they both contain the equivalnet value at the same type index.

Instance details

Defined in Data.Diverse.Which.Internal

Methods

(==) :: Which (x ': xs) -> Which (x ': xs) -> Bool

(/=) :: Which (x ': xs) -> Which (x ': xs) -> Bool

Eq (Which ('[] :: [Type])) Source #
(zilch == zilch) == True
Instance details

Defined in Data.Diverse.Which.Internal

Methods

(==) :: Which '[] -> Which '[] -> Bool

(/=) :: Which '[] -> Which '[] -> Bool

(Switch (CaseEqWhich :: Type -> [Type] -> Type) Bool (x ': xs), Switch (CaseOrdWhich :: Type -> [Type] -> Type) Ordering (x ': xs)) => Ord (Which (x ': xs)) Source #

A Which with a type at smaller type index is considered smaller.

Instance details

Defined in Data.Diverse.Which.Internal

Methods

compare :: Which (x ': xs) -> Which (x ': xs) -> Ordering

(<) :: Which (x ': xs) -> Which (x ': xs) -> Bool

(<=) :: Which (x ': xs) -> Which (x ': xs) -> Bool

(>) :: Which (x ': xs) -> Which (x ': xs) -> Bool

(>=) :: Which (x ': xs) -> Which (x ': xs) -> Bool

max :: Which (x ': xs) -> Which (x ': xs) -> Which (x ': xs)

min :: Which (x ': xs) -> Which (x ': xs) -> Which (x ': xs)

Ord (Which ('[] :: [Type])) Source #
(compare zilch zilch) == EQ
Instance details

Defined in Data.Diverse.Which.Internal

Methods

compare :: Which '[] -> Which '[] -> Ordering

(<) :: Which '[] -> Which '[] -> Bool

(<=) :: Which '[] -> Which '[] -> Bool

(>) :: Which '[] -> Which '[] -> Bool

(>=) :: Which '[] -> Which '[] -> Bool

max :: Which '[] -> Which '[] -> Which '[]

min :: Which '[] -> Which '[] -> Which '[]

Reduce (Which xs) (SwitcherN c r n xs) => SwitchN Which (c :: Type -> Nat -> [Type] -> Type) r n (xs :: [Type]) Source # 
Instance details

Defined in Data.Diverse.Which.Internal

Methods

switchN :: Which xs -> c r n xs -> r Source #

Reduce (Which '[Void]) (Switcher c r ('[] :: [Type])) Source #

Allow 'Which '[Void]' to be reinterpret'ed or diversifyed into anything else This is safe because Which '[Void] is uninhabited, and this is already something that can be done with impossible

Instance details

Defined in Data.Diverse.Which.Internal

Methods

reduce :: Switcher c r '[] -> Which '[Void] -> Reduced (Switcher c r '[]) Source #

(Case (c r) (x ': (x' ': xs)), Reduce (Which (x' ': xs)) (Switcher c r (x' ': xs)), Reiterate (c r) (x ': (x' ': xs)), r ~ CaseResult (c r) x) => Reduce (Which (x ': (x' ': xs))) (Switcher c r (x ': (x' ': xs))) Source #

trial0 each type in a Which, and either handle the case' with value discovered, or reiterate trying the next type in the type list.

Instance details

Defined in Data.Diverse.Which.Internal

Methods

reduce :: Switcher c r (x ': (x' ': xs)) -> Which (x ': (x' ': xs)) -> Reduced (Switcher c r (x ': (x' ': xs))) Source #

(Case (c r) '[x], r ~ CaseResult (c r) x) => Reduce (Which '[x]) (Switcher c r '[x]) Source #

Terminating case of the loop, ensuring that a instance of Case '[] with an empty typelist is not required.

Instance details

Defined in Data.Diverse.Which.Internal

Methods

reduce :: Switcher c r '[x] -> Which '[x] -> Reduced (Switcher c r '[x]) Source #

Reduce (Which ('[] :: [Type])) (Switcher c r ('[] :: [Type])) Source #

Allow 'Which '[]' to be reinterpret'ed or diversifyed into anything else This is safe because Which '[] is uninhabited, and this is already something that can be done with impossible

Instance details

Defined in Data.Diverse.Which.Internal

Methods

reduce :: Switcher c r '[] -> Which '[] -> Reduced (Switcher c r '[]) Source #

(Case (c r n) (x ': (x' ': xs)), Reduce (Which (x' ': xs)) (SwitcherN c r (n + 1) (x' ': xs)), ReiterateN (c r) n (x ': (x' ': xs)), r ~ CaseResult (c r n) x) => Reduce (Which (x ': (x' ': xs))) (SwitcherN c r n (x ': (x' ': xs))) Source #

trial0 each type in a Which, and either handle the case' with value discovered, or reiterateN trying the next type in the type list.

Instance details

Defined in Data.Diverse.Which.Internal

Methods

reduce :: SwitcherN c r n (x ': (x' ': xs)) -> Which (x ': (x' ': xs)) -> Reduced (SwitcherN c r n (x ': (x' ': xs))) Source #

(Case (c r n) '[x], r ~ CaseResult (c r n) x) => Reduce (Which '[x]) (SwitcherN c r n '[x]) Source #

Terminating case of the loop, ensuring that a instance of Case '[] with an empty typelist is not required. You can't reduce zilch

Instance details

Defined in Data.Diverse.Which.Internal

Methods

reduce :: SwitcherN c r n '[x] -> Which '[x] -> Reduced (SwitcherN c r n '[x]) Source #

type Rep (Which (x ': (x' ': xs))) Source # 
Instance details

Defined in Data.Diverse.Which.Internal

type Rep (Which (x ': (x' ': xs))) = Rec0 x :+: Rec0 (Which (x' ': xs))
type Rep (Which '[x]) Source # 
Instance details

Defined in Data.Diverse.Which.Internal

type Rep (Which '[x]) = Rec0 x
type Rep (Which ('[] :: [Type])) Source # 
Instance details

Defined in Data.Diverse.Which.Internal

type Rep (Which ('[] :: [Type])) = V1 :: Type -> Type

Single type

Construction

impossible :: Which '[] -> a Source #

Analogous to absurd. Renamed impossible to avoid conflicts.

Since 'Which '[]' values logically don't exist, this witnesses the logical reasoning tool of "ex falso quodlibet", ie "from falsehood, anything follows".

A 'Which '[]' is a Which with no alternatives, which may occur as a Left-over from trialing a Which '[x] with one type. It is an uninhabited type, just like Void

impossible' :: Which '[Void] -> a Source #

A Which '[Void] is equivalent to Which '[] A Which '[Void] might occur if you lift a Void into a Which with pick. This allows you to convert it back to Void or Which '[]

pick :: forall x xs. UniqueMember x xs => x -> Which xs Source #

Lift a value into a Which of possibly other types xs. xs can be inferred or specified with TypeApplications. NB. forall is used to specify xs first, so TypeApplications can be used to specify xs first

pick 'A' @_ @'[Int, Bool, Char, Maybe String] :: Which '[Int, Bool, Char, Maybe String]

pick0 :: x -> Which (x ': xs) Source #

A variation of pick into a Which where x is the first type.

pick0 'A' :: Which '[Char, Int, Bool]

pickOnly :: x -> Which '[x] Source #

A variation of pick into a Which of a single type.

pickOnly 'A' :: Which '[Char]

pickL :: forall l x xs. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => x -> Which xs Source #

A variation of pick where x is specified via a label

let y = pickL @Foo (Tagged (5 :: Int)) :: Which '[Bool, Tagged Foo Int, Tagged Bar Char]
    x = trialL @Foo y
x shouldBe (Right (Tagged 5))

pickTag :: forall l x xs. UniqueMember (Tagged l x) xs => x -> Which xs Source #

Variation of pick specialized to Tagged that automatically tags the value.

pickN :: forall n x xs. MemberAt n x xs => x -> Which xs Source #

Lift a value into a Which of possibly other (possibley indistinct) types, where the value is the n-th type.

pickN @4 (5 :: Int) :: Which '[Bool, Int, Char, Bool, Int, Char]

Destruction

obvious :: Which '[a] -> a Source #

It is obvious what value is inside a Which of one type.

let x = pick' 'A' :: Which '[Char]
obvious x `shouldBe` 'A'

trial :: forall x xs. UniqueMember x xs => Which xs -> Either (Which (Remove x xs)) x Source #

trial a type in a Which and Either get the Right value or the Left-over possibilities.

let x = pick 'A' @'[Int, Bool, Char, Maybe String] :: Which '[Int, Bool, Char, Maybe String]
trial @Char x `shouldBe` Right 'A'
trial @Int x `shouldBe` Left (pick 'A') :: Which '[Bool, Char, Maybe String]

trial' :: forall x xs. UniqueMember x xs => Which xs -> Maybe x Source #

Variation of trial which returns a Maybe

trial0 :: forall x xs. Which (x ': xs) -> Either (Which xs) x Source #

A variation of a Which trial which trials the first type in the type list.

let x = pick 'A' @'[Int, Bool, Char, Maybe String] :: Which '[Int, Bool, Char, Maybe String]
trial0 x `shouldBe` Left (pick 'A') :: Which '[Bool, Char, Maybe String]

trial0' :: forall x xs. Which (x ': xs) -> Maybe x Source #

Variation of trial0 which returns a Maybe

trialL :: forall l x xs. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => Which xs -> Either (Which (Remove x xs)) x Source #

A variation of trial where x is specified via a label

let y = pickL @Foo (Tagged (5 :: Int)) :: Which '[Bool, Tagged Foo Int, Tagged Bar Char]
    x = trialL @Foo Proxy y
x shouldBe (Right (Tagged 5))

trialL' :: forall l x xs. (UniqueLabelMember l xs, x ~ KindAtLabel l xs) => Which xs -> Maybe x Source #

Variation of trialL which returns a Maybe

trialTag :: forall l x xs. UniqueMember (Tagged l x) xs => Which xs -> Either (Which (Remove (Tagged l x) xs)) x Source #

Variation of trialL specialized to Tagged which untags the field.

trialTag' :: forall l x xs. UniqueMember (Tagged l x) xs => Which xs -> Maybe x Source #

Variation of trialL' specialized to Tagged which untags the field.

trialN :: forall n x xs. MemberAt n x xs => Which xs -> Either (Which (RemoveIndex n xs)) x Source #

trialN the n-th type of a Which, and get Either the Right value or the Left-over possibilities.

let x = pick 'A' @_ @'[Int, Bool, Char, Maybe String] :: Which '[Int, Bool, Char, Maybe String]
trialN @1 x `shouldBe` Left (pick 'A') :: Which '[Int, Char, Maybe String]

trialN' :: forall n x xs. MemberAt n x xs => Which xs -> Maybe x Source #

Variation of trialN which returns a Maybe

pattern W :: forall x xs. UniqueMember x xs => x -> Which xs Source #

Pattern synonym that makes pattern matching on Which possible. For example, this will return Just 5:

let y = pick (5 :: Int) :: Which '[Bool, String, Int]
in  case y of
      W (i :: Int) -> Just i
      _ -> Nothing

Keep in mind, GHC is not smart enough and will always throw a warning about incomplete pattern matches without a catch-all clause.

Multiple types

Injection

type Diversify (branch :: [Type]) (tree :: [Type]) = Switch (CaseDiversify branch tree) (Which tree) branch Source #

A friendlier constraint synonym for diversify.

diversify :: forall branch tree. Diversify branch tree => Which branch -> Which tree Source #

Convert a Which to another Which that may include other possibilities. That is, branch is equal or is a subset of tree.

This can also be used to rearrange the order of the types in the Which.

It is a compile error if tree has duplicate types with branch.

NB. Use TypeApplications with _ to specify tree@.

let a = pick' (5 :: Int) :: Which '[Int]
    b = diversify @_ @[Int, Bool] a :: Which '[Int, Bool]
    c = diversify @_ @[Bool, Int] b :: Which '[Bool, Int]

diversify' :: forall branch tree. (Diversify branch tree, SameLength branch tree) => Which branch -> Which tree Source #

A restricted version of diversify which only rearranges the types

diversify0 :: forall x xs. Which xs -> Which (x ': xs) Source #

A simple version of diversify which add another type to the front of the typelist.

type DiversifyL (ls :: [k]) (branch :: [Type]) (tree :: [Type]) = (Diversify branch tree, branch ~ KindsAtLabels ls tree, UniqueLabels ls tree, IsDistinct ls) Source #

A friendlier constraint synonym for diversifyL.

diversifyL :: forall ls branch tree. DiversifyL ls branch tree => Which branch -> Which tree Source #

A variation of diversify where branchis additionally specified by a labels list.

let y = pickOnly (5 :: Tagged Bar Int)
    y' = diversifyL @'[Bar] y :: Which '[Tagged Bar Int, Tagged Foo Bool]
    y'' = diversifyL @'[Bar, Foo] y' :: Which '[Tagged Foo Bool, Tagged Bar Int]
switch y'' (CaseFunc @Typeable (show . typeRep . (pure @Proxy))) `shouldBe` "Tagged * Bar Int"

type DiversifyN (ns :: [Nat]) (branch :: [Type]) (tree :: [Type]) = (SwitchN Which (CaseDiversifyN ns) (Which tree) 0 branch, KindsAtIndices ns tree ~ branch) Source #

A friendlier constraint synonym for diversifyN.

diversifyN :: forall ns branch tree. DiversifyN ns branch tree => Which branch -> Which tree Source #

A variation of diversify which uses a Nat list indices to specify how to reorder the fields, where

indices[branch_idx] = tree_idx

This variation allows tree to contain duplicate types with branch since the mapping is specified by indicies.

let y = pickOnly (5 :: Int)
    y' = diversifyN @'[0] @_ @[Int, Bool] y
    y'' = diversifyN @[1,0] @_ @[Bool, Int] y'
switch y'' (CaseFunc @Typeable (show . typeRep . (pure @Proxy))) `shouldBe` "Int"

Inverse Injection

type Reinterpret (branch :: [Type]) (tree :: [Type]) = Switch (CaseReinterpret branch tree) (Either (Which (Complement tree branch)) (Which branch)) tree Source #

A friendlier constraint synonym for reinterpret.

reinterpret :: forall branch tree. Reinterpret branch tree => Which tree -> Either (Which (Complement tree branch)) (Which branch) Source #

Convert a Which into possibly another Which with a totally different typelist. Returns either a Which with the Right value, or a Which with the Leftover compliment types.

It is a compile error if branch or compliment has duplicate types with tree.

NB. forall used to specify branch first, so TypeApplications can be used to specify branch first.

    let a = pick @[Int, Char, Bool] (5 :: Int) :: Which '[Int, Char, Bool]
    let  b = reinterpret [String, Char] y
    b `shouldBe` Left (pick (5 :: Int)) :: Which '[Int, Bool]
    let c = reinterpret [String, Int] a
    c `shouldBe` Right (pick (5 :: Int)) :: Which '[String, Int]

type Reinterpret' (branch :: [Type]) (tree :: [Type]) = Switch (CaseReinterpret' branch tree) (Maybe (Which branch)) tree Source #

A friendlier constraint synonym for reinterpret'.

reinterpret' :: forall branch tree. Reinterpret' branch tree => Which tree -> Maybe (Which branch) Source #

Variation of reinterpret which returns a Maybe.

type ReinterpretL (ls :: [k]) (branch :: [Type]) (tree :: [Type]) = (Reinterpret branch tree, branch ~ KindsAtLabels ls tree, UniqueLabels ls tree, IsDistinct ls) Source #

A friendlier constraint synonym for reinterpretL.

reinterpretL :: forall ls branch tree. ReinterpretL ls branch tree => Which tree -> Either (Which (Complement tree branch)) (Which branch) Source #

A variation of reinterpret where the branch is additionally specified with a labels list.

let y = pick @[Tagged Bar Int, Tagged Foo Bool, Tagged Hi Char, Tagged Bye Bool] (5 :: Tagged Bar Int)
    y' = reinterpretL @[Foo, Bar] y
    x = pick @[Tagged Foo Bool, Tagged Bar Int] (5 :: Tagged Bar Int)
y' `shouldBe` Right x

type ReinterpretL' (ls :: [k]) (branch :: [Type]) (tree :: [Type]) = (Reinterpret' branch tree, branch ~ KindsAtLabels ls tree, UniqueLabels ls tree, IsDistinct ls) Source #

A friendlier constraint synonym for reinterpretL.

reinterpretL' :: forall ls branch tree. ReinterpretL' ls branch tree => Which tree -> Maybe (Which branch) Source #

Variation of reinterpretL which returns a Maybe.

type ReinterpretN' (ns :: [Nat]) (branch :: [Type]) (tree :: [Type]) = (SwitchN Which (CaseReinterpretN' ns) (Maybe (Which branch)) 0 tree, KindsAtIndices ns tree ~ branch) Source #

A friendlier constraint synonym for reinterpretN.

reinterpretN' :: forall ns branch tree. ReinterpretN' ns branch tree => Which tree -> Maybe (Which branch) Source #

A limited variation of reinterpret' which uses a Nat list n to specify how to reorder the fields, where

indices[branch_idx] = tree_idx

This variation allows tree to contain duplicate types with branch since the mapping is specified by indicies.

However, unlike reinterpert, in this variation, branch must be a subset of tree instead of any arbitrary Which. Also it returns a Maybe instead of Either.

This is so that the same indices can be used in narrowN.

Catamorphism

type Switch c r xs = Reduce (Which xs) (Switcher c r xs) Source #

A friendlier constraint synonym for reinterpretN.

switch :: Switch c r xs => Which xs -> c r xs -> r Source #

A switch/case statement for Which. This is equivalent to flip which

Use Case instances like Cases to apply a Which of functions to a variant of values.

let y = pick (5 :: Int) :: Which '[Int, Bool]
switch y (
    cases (show @Bool
        ./ show @Int
        ./ nil)) `shouldBe` "5"

Or CaseFunc @Typeable to apply a polymorphic function that work on all Typeables.

let y = pick (5 :: Int) :: Which '[Int, Bool]
switch y (CaseFunc @Typeable (show . typeRep . (pure @Proxy))) `shouldBe` Int

Or you may use your own custom instance of Case.

which :: Switch c r xs => c r xs -> Which xs -> r Source #

Catamorphism for Which. This is flip switch.

newtype Switcher c r (xs :: [Type]) Source #

Switcher is an instance of Reduce for which reiterates through the possibilities in a Which, delegating handling to Case, ensuring termination when Which only contains one type.

Constructors

Switcher (c r xs) 

Instances

Instances details
Reduce Void (Switcher c r ('[] :: [Type])) Source #

Allow Void to be reinterpret'ed or diversifyed into anything else This is safe because Void is uninhabited, and this is already something that can be done with impossible

Instance details

Defined in Data.Diverse.Which.Internal

Methods

reduce :: Switcher c r '[] -> Void -> Reduced (Switcher c r '[]) Source #

Reduce (Which '[Void]) (Switcher c r ('[] :: [Type])) Source #

Allow 'Which '[Void]' to be reinterpret'ed or diversifyed into anything else This is safe because Which '[Void] is uninhabited, and this is already something that can be done with impossible

Instance details

Defined in Data.Diverse.Which.Internal

Methods

reduce :: Switcher c r '[] -> Which '[Void] -> Reduced (Switcher c r '[]) Source #

(Case (c r) (x ': (x' ': xs)), Reduce (Which (x' ': xs)) (Switcher c r (x' ': xs)), Reiterate (c r) (x ': (x' ': xs)), r ~ CaseResult (c r) x) => Reduce (Which (x ': (x' ': xs))) (Switcher c r (x ': (x' ': xs))) Source #

trial0 each type in a Which, and either handle the case' with value discovered, or reiterate trying the next type in the type list.

Instance details

Defined in Data.Diverse.Which.Internal

Methods

reduce :: Switcher c r (x ': (x' ': xs)) -> Which (x ': (x' ': xs)) -> Reduced (Switcher c r (x ': (x' ': xs))) Source #

(Case (c r) '[x], r ~ CaseResult (c r) x) => Reduce (Which '[x]) (Switcher c r '[x]) Source #

Terminating case of the loop, ensuring that a instance of Case '[] with an empty typelist is not required.

Instance details

Defined in Data.Diverse.Which.Internal

Methods

reduce :: Switcher c r '[x] -> Which '[x] -> Reduced (Switcher c r '[x]) Source #

Reduce (Which ('[] :: [Type])) (Switcher c r ('[] :: [Type])) Source #

Allow 'Which '[]' to be reinterpret'ed or diversifyed into anything else This is safe because Which '[] is uninhabited, and this is already something that can be done with impossible

Instance details

Defined in Data.Diverse.Which.Internal

Methods

reduce :: Switcher c r '[] -> Which '[] -> Reduced (Switcher c r '[]) Source #

type Reduced (Switcher c r xs) Source # 
Instance details

Defined in Data.Diverse.Which.Internal

type Reduced (Switcher c r xs) = r

class SwitchN w c r (n :: Nat) xs Source #

A switch/case statement for Which. This is equivalent to flip whichN

Use Case instances like CasesN to apply a Which of functions to a variant of values in index order.

let y = pickN @0 (5 :: Int) :: Which '[Int, Bool, Bool, Int]
switchN y (
    casesN (show @Int
        ./ show @Bool
        ./ show @Bool
        ./ show @Int
        ./ nil)) `shouldBe` "5"

Or you may use your own custom instance of Case.

Minimal complete definition

switchN

Instances

Instances details
Reduce (Which xs) (SwitcherN c r n xs) => SwitchN Which (c :: Type -> Nat -> [Type] -> Type) r n (xs :: [Type]) Source # 
Instance details

Defined in Data.Diverse.Which.Internal

Methods

switchN :: Which xs -> c r n xs -> r Source #

switchN :: SwitchN w c r n xs => w xs -> c r n xs -> r Source #

whichN :: SwitchN w c r n xs => c r n xs -> w xs -> r Source #

Catamorphism for Which. This is equivalent to flip switchN.

newtype SwitcherN c r (n :: Nat) (xs :: [Type]) Source #

SwitcherN is a variation of Switcher which reiterateNs through the possibilities in a Which, delegating work to CaseN, ensuring termination when Which only contains one type.

Constructors

SwitcherN (c r n xs) 

Instances

Instances details
(Case (c r n) (x ': (x' ': xs)), Reduce (Which (x' ': xs)) (SwitcherN c r (n + 1) (x' ': xs)), ReiterateN (c r) n (x ': (x' ': xs)), r ~ CaseResult (c r n) x) => Reduce (Which (x ': (x' ': xs))) (SwitcherN c r n (x ': (x' ': xs))) Source #

trial0 each type in a Which, and either handle the case' with value discovered, or reiterateN trying the next type in the type list.

Instance details

Defined in Data.Diverse.Which.Internal

Methods

reduce :: SwitcherN c r n (x ': (x' ': xs)) -> Which (x ': (x' ': xs)) -> Reduced (SwitcherN c r n (x ': (x' ': xs))) Source #

(Case (c r n) '[x], r ~ CaseResult (c r n) x) => Reduce (Which '[x]) (SwitcherN c r n '[x]) Source #

Terminating case of the loop, ensuring that a instance of Case '[] with an empty typelist is not required. You can't reduce zilch

Instance details

Defined in Data.Diverse.Which.Internal

Methods

reduce :: SwitcherN c r n '[x] -> Which '[x] -> Reduced (SwitcherN c r n '[x]) Source #

type Reduced (SwitcherN c r n xs) Source # 
Instance details

Defined in Data.Diverse.Which.Internal

type Reduced (SwitcherN c r n xs) = r