{-# 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.

--

-- @since 0.2

empty :: forall a. Data a => a
empty :: forall a. Data a => 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 :: Data a => a
general = (forall a. Data a => a) -> Constr -> a
forall a. Data a => (forall a. Data a => a) -> Constr -> a
fromConstrB d
forall a. Data a => a
empty (DataType -> Int -> Constr
indexConstr (a -> DataType
forall a. Data a => a -> DataType
dataTypeOf a
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.

--

-- @since 0.2

constrs :: forall a. Data a => [a]
constrs :: forall a. Data a => [a]
constrs = [a]
Data a => [a]
general
      [a] -> String -> [a]
forall a b. (Typeable a, Typeable b) => a -> b -> a
`extB` String
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 :: Data a => [a]
general = (Constr -> a) -> [Constr] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map ((forall a. Data a => a) -> Constr -> a
forall a. Data a => (forall a. Data a => a) -> Constr -> a
fromConstrB d
forall a. Data a => a
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 :: Data a => [a] -> a
unList = [a] -> a
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]