    {-# LANGUAGE ScopedTypeVariables  #-}
    {-# LANGUAGE FlexibleContexts     #-}

    -----------------------------------------------------------------------------

    -- |

    -- Module      :  Data.Generics.Builders

    -- Copyright   :  (c) 2008 Universiteit Utrecht

    -- License     :  BSD-style

    --

    -- Maintainer  :  generics@haskell.org

    -- Stability   :  experimental

    -- Portability :  non-portable

    --

    -- This module provides generic builder functions. These functions construct

    -- values of a given type.

    -----------------------------------------------------------------------------

    module Data.Generics.Builders (empty, constrs) where

    import Data.Data
    import Data.Generics.Aliases (extB)

    -- | Construct the empty value for a datatype. For algebraic datatypes, the

    -- leftmost constructor is chosen.

    empty :: forall a. Data a => a
    empty :: a
    empty = a
    Data a => a
    general
          a -> Char -> a
    forall a b. (Typeable a, Typeable b) => a -> b -> a
    `extB` Char
    char
          a -> Int -> a
    forall a b. (Typeable a, Typeable b) => a -> b -> a
    `extB` Int
    int
          a -> Integer -> a
    forall a b. (Typeable a, Typeable b) => a -> b -> a
    `extB` Integer
    integer
          a -> Float -> a
    forall a b. (Typeable a, Typeable b) => a -> b -> a
    `extB` Float
    float
          a -> Double -> a
    forall a b. (Typeable a, Typeable b) => a -> b -> a
    `extB` Double
    double where
      -- Generic case

      general :: Data a => a
      general :: a
    general = (forall d. Data d => d) -> Constr -> a
    forall a. Data a => (forall d. Data d => d) -> Constr -> a
    fromConstrB forall d. Data d => d
    empty (DataType -> Int -> Constr
    indexConstr (a -> DataType
    forall a. Data a => a -> DataType
    dataTypeOf a
    Data a => a
    general) 1)

      -- Base cases

      char :: Char
    char    = '\NUL'
      int :: Int
    int     = 0      :: Int
      integer :: Integer
    integer = 0      :: Integer
      float :: Float
    float   = 0.0    :: Float
      double :: Double
    double  = 0.0    :: Double

    -- | Return a list of values of a datatype. Each value is one of the possible

    -- constructors of the datatype, populated with 'empty' values.

    constrs :: forall a. Data a => [a]
    constrs :: [a]
    constrs = [a]
    Data a => [a]
    general
          [a] -> [Char] -> [a]
    forall a b. (Typeable a, Typeable b) => a -> b -> a
    `extB` [Char]
    char
          [a] -> [Int] -> [a]
    forall a b. (Typeable a, Typeable b) => a -> b -> a
    `extB` [Int]
    int
          [a] -> [Integer] -> [a]
    forall a b. (Typeable a, Typeable b) => a -> b -> a
    `extB` [Integer]
    integer
          [a] -> [Float] -> [a]
    forall a b. (Typeable a, Typeable b) => a -> b -> a
    `extB` [Float]
    float
          [a] -> [Double] -> [a]
    forall a b. (Typeable a, Typeable b) => a -> b -> a
    `extB` [Double]
    double where
      -- Generic case

      general :: Data a => [a]
      general :: [a]
    general = (Constr -> a) -> [Constr] -> [a]
    forall a b. (a -> b) -> [a] -> [b]
    map ((forall d. Data d => d) -> Constr -> a
    forall a. Data a => (forall d. Data d => d) -> Constr -> a
    fromConstrB forall d. Data d => d
    empty)
                  (DataType -> [Constr]
    dataTypeConstrs (a -> DataType
    forall a. Data a => a -> DataType
    dataTypeOf (Data a => [a] -> a
    [a] -> a
    unList [a]
    Data a => [a]
    general))) where
        unList :: Data a => [a] -> a
        unList :: [a] -> a
    unList = [a] -> a
    forall a. HasCallStack => a
    undefined

      -- Base cases

      char :: [Char]
    char    = "\NUL"
      int :: [Int]
    int     = [0   :: Int]
      integer :: [Integer]
    integer = [0   :: Integer]
      float :: [Float]
    float   = [0.0 :: Float]
      double :: [Double]
    double  = [0.0 :: Double]