    -----------------------------------------------------------------------------
    -- |
    -- Module      : Data.Array.Parallel.Base.Rebox
    -- Copyright   : (c) [2006,2007] Roman Leshchinskiy
    -- License     : see libraries/ndp/LICENSE
    --
    -- Maintainer  : Roman Leshchinskiy <rl@cse.unsw.edu.au>
    -- Stability   : internal
    -- Portability : non-portable (existentials)
    --
    --
    -- Reboxing support for SpecConstr; should go away eventually.
    --

    module Data.Array.Parallel.Base.Rebox (
      Rebox(..), Box(..)
    ) where

    import Data.Array.Parallel.Base.Hyperstrict

    import GHC.Base   (Int(..), Char(..))
    import GHC.Float  (Float(..), Double(..))

    class Rebox a where
      rebox :: a -> a
      dseq  :: a -> b -> b

    instance Rebox () where
      {-# INLINE [0] rebox #-}
      rebox () = ()

      {-# INLINE [0] dseq #-}
      dseq = seq

    instance Rebox Bool where
      {-# INLINE [0] rebox #-}
      rebox True = True
      rebox False = False

      {-# INLINE [0] dseq #-}
      dseq = seq

    instance Rebox Char where
      {-# INLINE [0] rebox #-}
      rebox (C# c#) = id (C# c#)

      {-# INLINE [0] dseq #-}
      dseq = seq

    instance Rebox Int where
      {-# INLINE [0] rebox #-}
      rebox (I# i#) = id (I# i#)

      {-# INLINE [0] dseq #-}
      dseq = seq

    instance Rebox Float where
      {-# INLINE [0] rebox #-}
      rebox (F# f#) = F# f#

      {-# INLINE [0] dseq #-}
      dseq = seq

    instance Rebox Double where
      {-# INLINE [0] rebox #-}
      rebox (D# d#) = D# d#

      {-# INLINE [0] dseq #-}
      dseq = seq

    instance (Rebox a, Rebox b) => Rebox (a :*: b) where
      {-# INLINE [0] rebox #-}
      rebox (x :*: y) = rebox x :*: rebox y

      {-# INLINE [0] dseq #-}
      dseq (x :*: y) z = dseq x (dseq y z)

    instance (Rebox a, Rebox b) => Rebox (EitherS a b) where
      {-# INLINE [0] rebox #-}
      rebox (LeftS  x) = LeftS  (rebox x)
      rebox (RightS y) = RightS (rebox y)

      {-# INLINE [0] dseq #-}
      dseq (LeftS  x) z = dseq x z
      dseq (RightS y) z = dseq y z

    instance Rebox a => Rebox (MaybeS a) where
      {-# INLINE [0] rebox #-}
      rebox NothingS  = NothingS
      rebox (JustS x) = JustS (rebox x)

      {-# INLINE [0] dseq #-}
      dseq NothingS  y = y
      dseq (JustS x) y = dseq x y

    newtype Box a = Box a

    instance Rebox (Box a) where
      {-# INLINE [0] rebox #-}
      rebox (Box a) = Box a

      {-# INLINE [0] dseq #-}
      dseq (Box a) x = x

    instance Rebox (Lazy a) where
      {-# INLINE [0] rebox #-}
      rebox (Lazy a) = Lazy a

      {-# INLINE [0] dseq #-}
      dseq (Lazy a) x = x