module Test.Agata.Instances where

import Test.Agata.Base

import Test.QuickCheck (arbitrary)


instance Buildable a => Buildable (Maybe a) where
  improve x = case x of
    Just a1 -> rebuild Just $ rb a1
    _ -> return x
  build =
    use Nothing ++
    Just $> autorec

    

instance (Buildable a, Buildable b) => Buildable (Either a b) where
  improve x = case x of
    Left a1 -> rebuild Left $ rb a1
    Right a1 -> rebuild Right $ rb a1
  build = 
    Left $> autorec ++
    Right $> autorec

instance Buildable a => Buildable [a] where
  improve x = case x of
    (a:b) -> rebuild (:) $ rb a *> rb b
    _     -> return x
  build = 
    use [] ++ 
    (:)  $> autorec .> rec


instance Buildable () where
  improve x = case x of
    _     -> return x
  build = use ()
    
instance Buildable Bool where
  improve x = case x of
    _     -> return x
  build = use True ++ use False


instance Buildable Char where
  dimension = return 0
  improve x = case x of
    _     -> return x
  build = graft arbitrary (\n -> (toInteger (n+1),take (n+1) ['a'..'z'] ))

      
      
instance Buildable Int where
  dimension = return 1
  improve x = case x of
    _     -> return x
  build = graft arbitrary (\n -> (toInteger (n+1),[0..n]) )








instance (Buildable a,Buildable b) => Buildable (a,b) where
  improve x = case x of
    (a1, a2) -> rebuild (,) $ rb a1 *> rb a2
  build = (,) $> autorec . autorec

instance (Buildable a,Buildable b,Buildable c) => Buildable (a,b,c) where
  improve x = case x of
    (a1,a2,a3) -> 
      rebuild (,,) $ rb a1 *> rb a2 *> rb a3
  build =  (,,) $> autorec . autorec . autorec 


instance (Buildable a,Buildable b,Buildable c,Buildable d) => Buildable (a,b,c,d) where
  improve x = case x of
    (a1,a2,a3,a4) -> 
      rebuild (,,,) $ rb a1 *> rb a2 *> rb a3 *> rb a4
  build = (,,,) $> autorec . autorec . autorec . autorec


instance (Buildable a,Buildable b,Buildable c,Buildable d,Buildable e) => Buildable (a,b,c,d,e) where
  improve x = case x of
    (a1,a2,a3,a4,a5) -> 
      rebuild (,,,,) $ rb a1 *> rb a2 *> rb a3 *> rb a4 *> rb a5
  build = (,,,,) $> autorec . autorec . autorec . autorec . autorec


instance (Buildable a,Buildable b,Buildable c,Buildable d,Buildable e,Buildable f) => Buildable (a,b,c,d,e,f) where
  improve x = case x of
    (a1,a2,a3,a4,a5,a6) -> 
      rebuild (,,,,,) $ rb a1 *> rb a2 *> rb a3 *> rb a4 *> rb a5 *> rb a6 
  build = (,,,,,) $> autorec . autorec . autorec . autorec . autorec . autorec 


instance (Buildable a,Buildable b,Buildable c,Buildable d,Buildable e,Buildable f,Buildable g) => Buildable (a,b,c,d,e,f,g) where
  improve x = case x of
    (a1,a2,a3,a4,a5,a6,a7) -> 
      rebuild (,,,,,,) $ rb a1 *> rb a2 *> rb a3 *> rb a4 *> rb a5 *> rb a6 *> rb a7 
  build = (,,,,,,) $> autorec . autorec . autorec . autorec . autorec . autorec . autorec 


instance (Buildable a,Buildable b,Buildable c,Buildable d,Buildable e,Buildable f,Buildable g,Buildable h) => Buildable (a,b,c,d,e,f,g,h) where
  improve x = case x of
    (a1,a2,a3,a4,a5,a6,a7,a8) -> 
      rebuild (,,,,,,,) $ rb a1 *> rb a2 *> rb a3 *> rb a4 *> rb a5 *> rb a6 *> rb a7 *> rb a8
  build = (,,,,,,,) $> autorec . autorec . autorec . autorec . autorec . autorec . autorec . autorec 


instance (Buildable a,Buildable b,Buildable c,Buildable d,Buildable e,Buildable f,Buildable g,Buildable h,Buildable i) => Buildable (a,b,c,d,e,f,g,h,i) where
  improve x = case x of
    (a1,a2,a3,a4,a5,a6,a7,a8,a9) -> 
      rebuild (,,,,,,,,) $ rb a1 *> rb a2 *> rb a3 *> rb a4 *> rb a5 *> rb a6 *> rb a7 *> rb a8 *> rb a9
  build = (,,,,,,,,) $> autorec . autorec . autorec . autorec . autorec . autorec . autorec . autorec . autorec


instance (Buildable a,Buildable b,Buildable c,Buildable d,Buildable e,Buildable f,Buildable g,Buildable h,Buildable i,Buildable j) => Buildable (a,b,c,d,e,f,g,h,i,j) where
  improve x = case x of
    (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) -> 
      rebuild (,,,,,,,,,) $ rb a1 *> rb a2 *> rb a3 *> rb a4 *> rb a5 *> rb a6 *> rb a7 *> rb a8 *> rb a9 *> rb a10
  build = (,,,,,,,,,) $> autorec . autorec . autorec . autorec . autorec . autorec . autorec . autorec . autorec . autorec