HORIZON HASKELLDocslts/ghc-9.10.xc74966e2026-09-27Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27

Modulesop-core-0.5.0.2Haskell2010

Data.SOP.Classes

Classes for generalized combinators on SOP types.

In the SOP approach to generic programming, we're predominantly concerned with four structured datatypes:

  NP  :: (k -> Type) -> ( [k]  -> Type)   -- n-ary product
  NS  :: (k -> Type) -> ( [k]  -> Type)   -- n-ary sum
  POP :: (k -> Type) -> ([[k]] -> Type)   -- product of products
  SOP :: (k -> Type) -> ([[k]] -> Type)   -- sum of products

All of these have a kind that fits the following pattern:

  (k -> Type) -> (l -> Type)

These four types support similar interfaces. In order to allow reusing the same combinator names for all of these types, we define various classes in this module that allow the necessary generalization.

The classes typically lift concepts that exist for kinds Type or Type -> Type to datatypes of kind (k -> Type) -> (l -> Type). This module also derives a number of derived combinators.

The actual instances are defined in Data.SOP.NP and Data.SOP.NS.

  • 1 type
  • 9 classes
  • 24 values
  • Packagesop-core-0.5.0.2
  • Exports38
  • LanguageHaskell2010
  • LicenceBSD-3-Clause
  • SourceClasses.hs

Generalized applicative functor structure

0 declarations

Generalized pure

classclass HPure (h :: (k -> Type) -> l -> Type) where
#

A generalization of pure or return to higher kinds.

Methods

  • hpure :: SListIN h xs => (forall (a :: k). f a) -> h f xs

    Corresponds to pure directly.

    Instances:

    hpure, pure_NP  :: Data.SOP.Sing.SListI  xs  => (forall a. f a) -> NP  f xs
    hpure, pure_POP :: SListI2 xss => (forall a. f a) -> POP f xss
    
  • hcpure :: AllN h c xs => proxy c -> (forall (a :: k). c a => f a) -> h f xs

    A variant of hpure that allows passing in a constrained argument.

    Calling hcpure f s where s :: h f xs causes f to be applied at all the types that are contained in xs. Therefore, the constraint c has to be satisfied for all elements of xs, which is what AllN h c xs states.

    Instances:

    hcpure, cpure_NP  :: (All  c xs ) => proxy c -> (forall a. c a => f a) -> NP  f xs
    hcpure, cpure_POP :: (All2 c xss) => proxy c -> (forall a. c a => f a) -> POP f xss
    
Instances2HPure
  • HPure NPDefined in sop-core-0.5.0.2 · Data.SOP.NP
  • HPure POPDefined in sop-core-0.5.0.2 · Data.SOP.NP

Generalized <*>

newtypenewtype (-.->) (f :: k -> Type) (g :: k -> Type) (a :: k)
#

Lifted functions.

Constructors

valuefn :: (f a -> f' a) -> (-.->) f f' a
#

Construct a lifted function.

Same as Fn. Only available for uniformity with the higher-arity versions.

valuefn_2 :: (f a -> f' a -> f'' a) -> (-.->) f (f' -.-> f'') a
#

Construct a binary lifted function.

valuefn_3
  1. :: f a -> f' a -> f'' a -> f''' a
  2. -> (-.->) f (f' -.-> (f'' -.-> f''')) a
#

Construct a ternary lifted function.

valuefn_4
  1. :: f a -> f' a -> f'' a -> f''' a -> f'''' a
  2. -> (-.->) f (f' -.-> (f'' -.-> (f''' -.-> f''''))) a
#

Construct a quarternary lifted function.

familytype family Same (h :: (k1 -> Type) -> l1 -> Type) :: (k2 -> Type) -> l2 -> Type
#

Maps a structure to the same structure.

Instances4Same
  • type Same NP = NPDefined in sop-core-0.5.0.2 · Data.SOP.NP
  • type Same POP = POPDefined in sop-core-0.5.0.2 · Data.SOP.NP
  • type Same NS = NSDefined in sop-core-0.5.0.2 · Data.SOP.NS
  • type Same SOP = SOPDefined in sop-core-0.5.0.2 · Data.SOP.NS
familytype family Prod (h :: (k -> Type) -> l -> Type) :: (k -> Type) -> l -> Type
#

Maps a structure containing sums to the corresponding product structure.

Instances4Prod
  • type Prod NP = NPDefined in sop-core-0.5.0.2 · Data.SOP.NP
  • type Prod POP = POPDefined in sop-core-0.5.0.2 · Data.SOP.NP
  • type Prod NS = NPDefined in sop-core-0.5.0.2 · Data.SOP.NS
  • type Prod SOP = POPDefined in sop-core-0.5.0.2 · Data.SOP.NS
classclass (Prod (Prod h) ~ Prod h, HPure (Prod h)) => HAp (h :: (k -> Type) -> l -> Type) where
#

A generalization of <*>.

Methods

  • hap :: Prod h (f -.-> g) xs -> h f xs -> h g xs

    Corresponds to <*>.

    For products (NP) as well as products of products (POP), the correspondence is rather direct. We combine a structure containing (lifted) functions and a compatible structure containing corresponding arguments into a compatible structure containing results.

    The same combinator can also be used to combine a product structure of functions with a sum structure of arguments, which then results in another sum structure of results. The sum structure determines which part of the product structure will be used.

    Instances:

    hap, ap_NP  :: NP  (f -.-> g) xs  -> NP  f xs  -> NP  g xs
    hap, ap_NS  :: Data.SOP.NS.NP  (f -.-> g) xs  -> NS  f xs  -> NS  g xs
    hap, ap_POP :: POP (f -.-> g) xss -> POP f xss -> POP g xss
    hap, ap_SOP :: Data.SOP.NS.POP (f -.-> g) xss -> SOP f xss -> SOP g xss
    
Instances4HAp
  • HAp NPDefined in sop-core-0.5.0.2 · Data.SOP.NP
  • HAp POPDefined in sop-core-0.5.0.2 · Data.SOP.NP
  • HAp NSDefined in sop-core-0.5.0.2 · Data.SOP.NS
  • HAp SOPDefined in sop-core-0.5.0.2 · Data.SOP.NS

Derived functions

valuehliftA
  1. :: (SListIN (Prod h) xs, HAp h)
  2. => forall (a :: k). f a -> f' a
  3. -> h f xs
  4. -> h f' xs
#

A generalized form of liftA, which in turn is a generalized map.

Takes a lifted function and applies it to every element of a structure while preserving its shape.

Specification:

hliftA f xs = hpure (fn f) ` hap ` xs

Instances:

hliftA, liftA_NP  :: Data.SOP.Sing.SListI  xs  => (forall a. f a -> f' a) -> NP  f xs  -> NP  f' xs
hliftA, liftA_NS  :: Data.SOP.Sing.SListI  xs  => (forall a. f a -> f' a) -> NS  f xs  -> NS  f' xs
hliftA, liftA_POP :: SListI2 xss => (forall a. f a -> f' a) -> POP f xss -> POP f' xss
hliftA, liftA_SOP :: SListI2 xss => (forall a. f a -> f' a) -> SOP f xss -> SOP f' xss
valuehliftA2
  1. :: (SListIN (Prod h) xs, HAp h, HAp (Prod h))
  2. => forall (a :: k). f a -> f' a -> f'' a
  3. -> Prod h f xs
  4. -> h f' xs
  5. -> h f'' xs
#

A generalized form of liftA2, which in turn is a generalized zipWith.

Takes a lifted binary function and uses it to combine two structures of equal shape into a single structure.

It either takes two product structures to a product structure, or one product and one sum structure to a sum structure.

Specification:

hliftA2 f xs ys = hpure (fn_2 f) ` hap ` xs ` hap ` ys

Instances:

hliftA2, liftA2_NP  :: Data.SOP.Sing.SListI  xs  => (forall a. f a -> f' a -> f'' a) -> NP  f xs  -> NP  f' xs  -> NP  f'' xs
hliftA2, liftA2_NS  :: Data.SOP.Sing.SListI  xs  => (forall a. f a -> f' a -> f'' a) -> NP  f xs  -> NS  f' xs  -> NS  f'' xs
hliftA2, liftA2_POP :: SListI2 xss => (forall a. f a -> f' a -> f'' a) -> POP f xss -> POP f' xss -> POP f'' xss
hliftA2, liftA2_SOP :: SListI2 xss => (forall a. f a -> f' a -> f'' a) -> POP f xss -> SOP f' xss -> SOP f'' xss
valuehliftA3
  1. :: (SListIN (Prod h) xs, HAp h, HAp (Prod h))
  2. => forall (a :: k). f a -> f' a -> f'' a -> f''' a
  3. -> Prod h f xs
  4. -> Prod h f' xs
  5. -> h f'' xs
  6. -> h f''' xs
#

A generalized form of liftA3, which in turn is a generalized zipWith3.

Takes a lifted ternary function and uses it to combine three structures of equal shape into a single structure.

It either takes three product structures to a product structure, or two product structures and one sum structure to a sum structure.

Specification:

hliftA3 f xs ys zs = hpure (fn_3 f) ` hap ` xs ` hap ` ys ` hap ` zs

Instances:

hliftA3, liftA3_NP  :: Data.SOP.Sing.SListI  xs  => (forall a. f a -> f' a -> f'' a -> f''' a) -> NP  f xs  -> NP  f' xs  -> NP  f'' xs  -> NP  f''' xs
hliftA3, Data.SOP.NS.liftA3_NS  :: Data.SOP.Sing.SListI  xs  => (forall a. f a -> f' a -> f'' a -> f''' a) -> NP  f xs  -> NP  f' xs  -> NS  f'' xs  -> NS  f''' xs
hliftA3, liftA3_POP :: SListI2 xss => (forall a. f a -> f' a -> f'' a -> f''' a) -> POP f xss -> POP f' xss -> POP f'' xss -> POP f''' xs
hliftA3, Data.SOP.NS.liftA3_SOP :: SListI2 xss => (forall a. f a -> f' a -> f'' a -> f''' a) -> POP f xss -> POP f' xss -> SOP f'' xss -> Data.SOP.NP.SOP f''' xs
valuehcliftA
  1. :: (AllN (Prod h) c xs, HAp h)
  2. => proxy c
  3. -> forall (a :: k). c a => f a -> f' a
  4. -> h f xs
  5. -> h f' xs
#

Variant of hliftA that takes a constrained function.

Specification:

hcliftA p f xs = hcpure p (fn f) ` hap ` xs
valuehcmap
  1. :: (AllN (Prod h) c xs, HAp h)
  2. => proxy c
  3. -> forall (a :: k). c a => f a -> f' a
  4. -> h f xs
  5. -> h f' xs
#

Another name for hcliftA.

Collapsing homogeneous structures

2 declarations
familytype family CollapseTo (h :: (k -> Type) -> l -> Type) x
#

Maps products to lists, and sums to identities.

Instances4CollapseTo
  • type CollapseTo NP a = [a]Defined in sop-core-0.5.0.2 · Data.SOP.NP
  • type CollapseTo POP a = [[a]]Defined in sop-core-0.5.0.2 · Data.SOP.NP
  • type CollapseTo NS a = aDefined in sop-core-0.5.0.2 · Data.SOP.NS
  • type CollapseTo SOP a = [a]Defined in sop-core-0.5.0.2 · Data.SOP.NS
classclass HCollapse (h :: (k -> Type) -> l -> Type) where
#

A class for collapsing a heterogeneous structure into a homogeneous one.

Methods

  • hcollapse :: SListIN h xs => h (K a) xs -> CollapseTo h a

    Collapse a heterogeneous structure with homogeneous elements into a homogeneous structure.

    If a heterogeneous structure is instantiated to the constant functor K, then it is in fact homogeneous. This function maps such a value to a simpler Haskell datatype reflecting that. An Data.SOP.NS (K a) contains a single a, and an Data.SOP.NP (K a) contains a list of as.

    Instances:

    hcollapse, collapse_NP  :: NP  (K a) xs  ->  [a]
    hcollapse, collapse_NS  :: NS  (K a) xs  ->   a
    hcollapse, collapse_POP :: POP (K a) xss -> [[a]]
    hcollapse, collapse_SOP :: Data.SOP.NP.SOP (K a) xss ->  [a]
    
Instances4HCollapse

Folding and sequencing

2 declarations
classclass HTraverse_ (h :: (k -> Type) -> l -> Type) where
#

A generalization of traverse_ or foldMap.

Methods

Instances4HTraverse_
classclass HAp h => HSequence (h :: (k -> Type) -> l -> Type) where
#

A generalization of sequenceA.

Methods

Instances4HSequence

Derived functions

Indexing into sums

1 declaration
classclass HIndex (h :: (k -> Type) -> l -> Type) where
#

A class for determining which choice in a sum-like structure a value represents.

Methods

  • hindex :: h f xs -> Int

    If h is a sum-like structure representing a choice between n different options, and x is a value of type h f xs, then hindex x returns a number between 0 and n - 1 representing the index of the choice made by x.

    Instances:

    hindex, index_NS  :: NS  f xs -> Int
    hindex, index_SOP :: SOP f xs -> Int
    

    Examples:

    Example3 expressions
    hindex (S (S (Z (I False))))2hindex (Z (K ()))0hindex (SOP (S (Z (I True :* I 'x' :* Nil))))1
Instances2HIndex
  • HIndex NSDefined in sop-core-0.5.0.2 · Data.SOP.NS
  • HIndex SOPDefined in sop-core-0.5.0.2 · Data.SOP.NS

Applying all injections

2 declarations
familytype family UnProd (h :: (k -> Type) -> l -> Type) :: (k -> Type) -> l -> Type
#

Maps a structure containing products to the corresponding sum structure.

Instances2UnProd
  • type UnProd NP = NSDefined in sop-core-0.5.0.2 · Data.SOP.NS · orphan
  • type UnProd POP = SOPDefined in sop-core-0.5.0.2 · Data.SOP.NS · orphan
classclass UnProd (Prod h) ~ h => HApInjs (h :: (k -> Type) -> l -> Type) where
#

A class for applying all injections corresponding to a sum-like structure to a table containing suitable arguments.

Methods

  • hapInjs :: SListIN h xs => Prod h f xs -> [h f xs]

    For a given table (product-like structure), produce a list where each element corresponds to the application of an injection function into the corresponding sum-like structure.

    Instances:

    hapInjs, apInjs_NP  :: Data.SOP.Sing.SListI  xs  => NP  f xs -> [NS  f xs ]
    hapInjs, Data.SOP.NS.apInjs_SOP :: SListI2 xss => POP f xs -> [SOP f xss]
    

    Examples:

    Example1 expression
    hapInjs (I 'x' :* I True :* I 2 :* Nil) :: [NS I '[Char, Bool, Int]][Z (I 'x'),S (Z (I True)),S (S (Z (I 2)))]
    Example1 expression
    hapInjs (POP ((I 'x' :* Nil) :* (I True :* I 2 :* Nil) :* Nil)) :: [SOP I '[ '[Char], '[Bool, Int]]][SOP (Z (I 'x' :* Nil)),SOP (S (Z (I True :* I 2 :* Nil)))]

    Unfortunately the type-signatures are required in GHC-7.10 and older.

Instances2HApInjs
  • HApInjs NSDefined in sop-core-0.5.0.2 · Data.SOP.NS
  • HApInjs SOPDefined in sop-core-0.5.0.2 · Data.SOP.NS

Expanding sums to products

1 declaration
classclass HExpand (h :: (k -> Type) -> l -> Type) where
#

A class for expanding sum structures into corresponding product structures, filling in the slots not targeted by the sum with default values.

Methods

  • hexpand :: SListIN (Prod h) xs => (forall (x :: k). f x) -> h f xs -> Prod h f xs

    Expand a given sum structure into a corresponding product structure by placing the value contained in the sum into the corresponding position in the product, and using the given default value for all other positions.

    Instances:

    hexpand, expand_NS  :: Data.SOP.Sing.SListI xs   => (forall x . f x) -> NS  f xs  -> Data.SOP.NS.NP  f xs
    hexpand, expand_SOP :: SListI2 xss => (forall x . f x) -> SOP f xss -> POP f xss
    

    Examples:

    Example2 expressions
    hexpand Nothing (S (Z (Just 3))) :: NP Maybe '[Char, Int, Bool]Nothing :* Just 3 :* Nothing :* Nilhexpand [] (SOP (S (Z ([1,2] :* "xyz" :* Nil)))) :: POP [] '[ '[Bool], '[Int, Char] ]POP (([] :* Nil) :* ([1,2] :* "xyz" :* Nil) :* Nil)
  • hcexpand :: AllN (Prod h) c xs => proxy c -> (forall (x :: k). c x => f x) -> h f xs -> Prod h f xs

    Variant of hexpand that allows passing a constrained default.

    Instances:

    hcexpand, cexpand_NS  :: All  c xs  => proxy c -> (forall x . c x => f x) -> NS  f xs  -> NP  f xs
    hcexpand, cexpand_SOP :: All2 c xss => proxy c -> (forall x . c x => f x) -> SOP f xss -> POP f xss
    

    Examples:

    Example2 expressions
    hcexpand (Proxy :: Proxy Bounded) (I minBound) (S (Z (I 20))) :: NP I '[Bool, Int, Ordering]I False :* I 20 :* I LT :* Nilhcexpand (Proxy :: Proxy Num) (I 0) (SOP (S (Z (I 1 :* I 2 :* Nil)))) :: POP I '[ '[Double], '[Int, Int] ]POP ((I 0.0 :* Nil) :* (I 1 :* I 2 :* Nil) :* Nil)
Instances2HExpand
  • HExpand NSDefined in sop-core-0.5.0.2 · Data.SOP.NS
  • HExpand SOPDefined in sop-core-0.5.0.2 · Data.SOP.NS

Transformation of index lists and coercions

3 declarations
classclass (Same h1 ~ h2, Same h2 ~ h1) => HTrans (h1 :: (k1 -> Type) -> l1 -> Type) (h2 :: (k2 -> Type) -> l2 -> Type) where
#

A class for transforming structures into related structures with a different index list, as long as the index lists have the same shape and the elements and interpretation functions are suitably related.

Methods

  • htrans :: AllZipN (Prod h1) c xs ys => proxy c -> (forall (x :: k1) (y :: k2). c x y => f x -> g y) -> h1 f xs -> h2 g ys

    Transform a structure into a related structure given a conversion function for the elements.

  • hcoerce :: AllZipN (Prod h1) (LiftedCoercible f g) xs ys => h1 f xs -> h2 g ys

    Safely coerce a structure into a representationally equal structure.

    This is a special case of htrans, but can be implemented more efficiently; for example in terms of unsafeCoerce.

    Examples:

    Example2 expressions
    hcoerce (I (Just LT) :* I (Just 'x') :* I (Just True) :* Nil) :: NP Maybe '[Ordering, Char, Bool]Just LT :* Just 'x' :* Just True :* Nilhcoerce (SOP (Z (K True :* K False :* Nil))) :: SOP I '[ '[Bool, Bool], '[Bool] ]SOP (Z (I True :* I False :* Nil))
Instances4HTrans
  • HTrans NP NPDefined in sop-core-0.5.0.2 · Data.SOP.NP
  • HTrans POP POPDefined in sop-core-0.5.0.2 · Data.SOP.NP
  • HTrans NS NSDefined in sop-core-0.5.0.2 · Data.SOP.NS
  • HTrans SOP SOPDefined in sop-core-0.5.0.2 · Data.SOP.NS