-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Basic examples and functions for generics-sop -- -- This library contains various small examples of generic functions -- written using the generics-sop library. -- -- It is a good starting point if you want to see how generic functions -- can be defined in the SOP style. @package basic-sop @version 0.2.0.1 -- | Generic computation of a skeleton. module Generics.SOP.Skeleton -- | Generic computation of a skeleton. -- -- A skeleton for a record type has a defined "spine" but is undefined -- everywhere else. For instance, a skeleton for pairs would be -- --
--   (undefined, undefined)
--   
-- -- We introduce a type class for this purpose because the skeleton for -- nested records would look like -- --
--   (undefined, (undefined, undefined))
--   
-- -- The default instance of skeleton applies to record types; for -- everything else, use undefined (or error): -- --
--   instance Skeleton SomeRecordType -- no where clause
--   
-- -- or -- --
--   instance Skeleton SomeNonRecordType where skeleton = undefined
--   
-- -- This is an example of how SOP-style generic functions can be used with -- DefaultSignatures. -- -- Furthermore, metadata is used in order to produce better error -- messages. For the undefined components of a record, an error is -- triggered that mentions the name of the field. class Skeleton a where skeleton = gskeleton -- | Returns a skeleton. skeleton :: (Skeleton a, Generic a, HasDatatypeInfo a, Code a ~ '[xs], All Skeleton xs) => a -- | Returns a skeleton. skeleton :: Skeleton a => a instance Generics.SOP.Skeleton.Skeleton [a] instance Generics.SOP.Skeleton.Skeleton (GHC.Base.Maybe a) instance Generics.SOP.Skeleton.Skeleton GHC.Types.Int instance Generics.SOP.Skeleton.Skeleton GHC.Types.Double instance Generics.SOP.Skeleton.Skeleton GHC.Real.Rational instance Generics.SOP.Skeleton.Skeleton GHC.Types.Bool instance Generics.SOP.Skeleton.Skeleton Data.Text.Internal.Text -- | Generic show. -- -- This module contains a generic show function defined using -- generics-sop. module Generics.SOP.Show -- | Generic show. -- -- This function is a proof-of-concept implementation of a function that -- is similar to the show function you get by using 'deriving -- Show'. -- -- It serves as an example of an SOP-style generic function that makes -- use of metadata. However, it does currently not handle parentheses -- correctly, and is therefore not really usable as a replacement. -- -- If you want to use it anyway on a datatype T for which you -- have a Generic instance, you can use gshow as follows: -- --
--   instance Show T where
--     show = gshow
--   
gshow :: forall a. (Generic a, HasDatatypeInfo a, All2 Show (Code a)) => a -> String -- | Generic reduction to normal form. -- -- This module contains a generic function that reduces a value to normal -- form, defined using generics-sop. module Generics.SOP.NFData -- | Generic reduction to normal form. -- -- This function is a generic implementation of the rnf function -- that can be used to instantiate the NFData class in -- deepseq. -- -- Assuming you have a Generic instance for your datatype -- T, you can use grnf as follows: -- --
--   instance NFData T where
--     rnf = grnf
--   
grnf :: (Generic a, All2 NFData (Code a)) => a -> () -- | Generic equality. -- -- This module contains a generic equality function defined using -- generics-sop. module Generics.SOP.Eq -- | Generic equality. -- -- This function reimplements the built-in generic equality that you get -- by using deriving Eq. -- -- Assuming you have a Generic instance for a datatype T, -- you can use geq as follows: -- --
--   instance Eq T where
--     (==) = geq
--   
geq :: (Generic a, All2 Eq (Code a)) => a -> a -> Bool -- | Generic generation of random test cases. -- -- This module contains a generic version of arbitrary from the -- Test.Quickcheck library, using generics-sop. module Generics.SOP.Arbitrary -- | Generic generation of random test cases. -- -- This function is a proof-of-concept implementation of a generic -- arbitrary that can be used to instantiate the Arbitrary -- class in QuickCheck. -- -- If you want to use it on a datatype T for which you have a -- Generic instance, you can say: -- --
--   instance Arbitrary T where
--     arbitrary = garbitrary
--   
-- -- Note that currently no attempts are being made to generate arbitrary -- values of a particular size, and it is possible that this function -- diverges for recursive structures. garbitrary :: forall a. (Generic a, All2 Arbitrary (Code a)) => Gen a -- | Random generation and shrinking of values. class Arbitrary a -- | A generator for values of the given type. arbitrary :: Arbitrary a => Gen a -- | Produces a (possibly) empty list of all the possible immediate shrinks -- of the given value. The default implementation returns the empty list, -- so will not try to shrink the value. -- -- Most implementations of shrink should try at least three -- things: -- --
    --
  1. Shrink a term to any of its immediate subterms.
  2. --
  3. Recursively apply shrink to all immediate subterms.
  4. --
  5. Type-specific shrinkings such as replacing a constructor by a -- simpler constructor.
  6. --
-- -- For example, suppose we have the following implementation of binary -- trees: -- --
--   data Tree a = Nil | Branch a (Tree a) (Tree a)
--   
-- -- We can then define shrink as follows: -- --
--   shrink Nil = []
--   shrink (Branch x l r) =
--     -- shrink Branch to Nil
--     [Nil] ++
--     -- shrink to subterms
--     [l, r] ++
--     -- recursively shrink subterms
--     [Branch x' l' r' | (x', l', r') <- shrink (x, l, r)]
--   
-- -- There are a couple of subtleties here: -- -- -- -- There is a fair bit of boilerplate in the code above. We can avoid it -- with the help of some generic functions; note that these only work on -- GHC 7.2 and above. The function genericShrink tries shrinking a -- term to all of its subterms and, failing that, recursively shrinks the -- subterms. Using it, we can define shrink as: -- --
--   shrink x = shrinkToNil x ++ genericShrink x
--     where
--       shrinkToNil Nil = []
--       shrinkToNil (Branch _ l r) = [Nil]
--   
-- -- genericShrink is a combination of subterms, which -- shrinks a term to any of its subterms, and recursivelyShrink, -- which shrinks all subterms of a term. These may be useful if you need -- a bit more control over shrinking than genericShrink gives you. -- -- A final gotcha: we cannot define shrink as simply -- shrink x = Nil:genericShrink x as this shrinks -- Nil to Nil, and shrinking will go into an infinite -- loop. -- -- If all this leaves you bewildered, you might try shrink = -- genericShrink to begin with, after deriving -- Generic for your type. However, if your data type has any -- special invariants, you will need to check that genericShrink -- can't break those invariants. shrink :: Arbitrary a => a -> [a]