{-# 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 :: forall a. Data a => a
empty = Data a => a
general 
      forall a b. (Typeable a, Typeable b) => a -> b -> a
`extB` Char
char 
      forall a b. (Typeable a, Typeable b) => a -> b -> a
`extB` Int
int
      forall a b. (Typeable a, Typeable b) => a -> b -> a
`extB` Integer
integer
      forall a b. (Typeable a, Typeable b) => a -> b -> a
`extB` Float
float 
      forall a b. (Typeable a, Typeable b) => a -> b -> a
`extB` Double
double where
  -- Generic case

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

  char :: Char
char    = Char
'\NUL'
  int :: Int
int     = Int
0      :: Int
  integer :: Integer
integer = Integer
0      :: Integer
  float :: Float
float   = Float
0.0    :: Float
  double :: 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 :: forall a. Data a => [a]
constrs = Data a => [a]
general
      forall a b. (Typeable a, Typeable b) => a -> b -> a
`extB` String
char
      forall a b. (Typeable a, Typeable b) => a -> b -> a
`extB` [Int]
int
      forall a b. (Typeable a, Typeable b) => a -> b -> a
`extB` [Integer]
integer
      forall a b. (Typeable a, Typeable b) => a -> b -> a
`extB` [Float]
float
      forall a b. (Typeable a, Typeable b) => a -> b -> a
`extB` [Double]
double where
  -- Generic case

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

  -- Base cases

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