{-# LANGUAGE ConstraintKinds   #-}
{-# LANGUAGE FlexibleContexts  #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MonoLocalBinds    #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
-- |
-- Module      : Data.Array.Accelerate.Classes.Enum
-- Copyright   : [2016..2020] The Accelerate Team
-- License     : BSD3
--
-- Maintainer  : Trevor L. McDonell <trevor.mcdonell@gmail.com>
-- Stability   : experimental
-- Portability : non-portable (GHC extensions)
--

module Data.Array.Accelerate.Classes.Enum (

  Enum,
  succ, pred,

) where

import Data.Array.Accelerate.Classes.Num
import Data.Array.Accelerate.Smart
import Data.Array.Accelerate.Type
import Text.Printf

import Prelude                                                      ( ($), String, error, unlines, succ, pred )
import qualified Prelude                                            as P


-- | Operations over sequentially ordered types
--
type Enum a = P.Enum (Exp a)


instance P.Enum (Exp Int) where
  succ :: Exp Int -> Exp Int
succ      = Exp Int -> Exp Int
forall a. Num a => Exp a -> Exp a
defaultSucc
  pred :: Exp Int -> Exp Int
pred      = Exp Int -> Exp Int
forall a. Num a => Exp a -> Exp a
defaultPred
  toEnum :: Int -> Exp Int
toEnum    = Int -> Exp Int
forall a. Int -> a
defaultToEnum
  fromEnum :: Exp Int -> Int
fromEnum  = Exp Int -> Int
forall a. a -> Int
defaultFromEnum

instance P.Enum (Exp Int8) where
  succ :: Exp Int8 -> Exp Int8
succ      = Exp Int8 -> Exp Int8
forall a. Num a => Exp a -> Exp a
defaultSucc
  pred :: Exp Int8 -> Exp Int8
pred      = Exp Int8 -> Exp Int8
forall a. Num a => Exp a -> Exp a
defaultPred
  toEnum :: Int -> Exp Int8
toEnum    = Int -> Exp Int8
forall a. Int -> a
defaultToEnum
  fromEnum :: Exp Int8 -> Int
fromEnum  = Exp Int8 -> Int
forall a. a -> Int
defaultFromEnum

instance P.Enum (Exp Int16) where
  succ :: Exp Int16 -> Exp Int16
succ      = Exp Int16 -> Exp Int16
forall a. Num a => Exp a -> Exp a
defaultSucc
  pred :: Exp Int16 -> Exp Int16
pred      = Exp Int16 -> Exp Int16
forall a. Num a => Exp a -> Exp a
defaultPred
  toEnum :: Int -> Exp Int16
toEnum    = Int -> Exp Int16
forall a. Int -> a
defaultToEnum
  fromEnum :: Exp Int16 -> Int
fromEnum  = Exp Int16 -> Int
forall a. a -> Int
defaultFromEnum

instance P.Enum (Exp Int32) where
  succ :: Exp Int32 -> Exp Int32
succ      = Exp Int32 -> Exp Int32
forall a. Num a => Exp a -> Exp a
defaultSucc
  pred :: Exp Int32 -> Exp Int32
pred      = Exp Int32 -> Exp Int32
forall a. Num a => Exp a -> Exp a
defaultPred
  toEnum :: Int -> Exp Int32
toEnum    = Int -> Exp Int32
forall a. Int -> a
defaultToEnum
  fromEnum :: Exp Int32 -> Int
fromEnum  = Exp Int32 -> Int
forall a. a -> Int
defaultFromEnum

instance P.Enum (Exp Int64) where
  succ :: Exp Int64 -> Exp Int64
succ      = Exp Int64 -> Exp Int64
forall a. Num a => Exp a -> Exp a
defaultSucc
  pred :: Exp Int64 -> Exp Int64
pred      = Exp Int64 -> Exp Int64
forall a. Num a => Exp a -> Exp a
defaultPred
  toEnum :: Int -> Exp Int64
toEnum    = Int -> Exp Int64
forall a. Int -> a
defaultToEnum
  fromEnum :: Exp Int64 -> Int
fromEnum  = Exp Int64 -> Int
forall a. a -> Int
defaultFromEnum

instance P.Enum (Exp Word) where
  succ :: Exp Word -> Exp Word
succ      = Exp Word -> Exp Word
forall a. Num a => Exp a -> Exp a
defaultSucc
  pred :: Exp Word -> Exp Word
pred      = Exp Word -> Exp Word
forall a. Num a => Exp a -> Exp a
defaultPred
  toEnum :: Int -> Exp Word
toEnum    = Int -> Exp Word
forall a. Int -> a
defaultToEnum
  fromEnum :: Exp Word -> Int
fromEnum  = Exp Word -> Int
forall a. a -> Int
defaultFromEnum

instance P.Enum (Exp Word8) where
  succ :: Exp Word8 -> Exp Word8
succ      = Exp Word8 -> Exp Word8
forall a. Num a => Exp a -> Exp a
defaultSucc
  pred :: Exp Word8 -> Exp Word8
pred      = Exp Word8 -> Exp Word8
forall a. Num a => Exp a -> Exp a
defaultPred
  toEnum :: Int -> Exp Word8
toEnum    = Int -> Exp Word8
forall a. Int -> a
defaultToEnum
  fromEnum :: Exp Word8 -> Int
fromEnum  = Exp Word8 -> Int
forall a. a -> Int
defaultFromEnum

instance P.Enum (Exp Word16) where
  succ :: Exp Word16 -> Exp Word16
succ      = Exp Word16 -> Exp Word16
forall a. Num a => Exp a -> Exp a
defaultSucc
  pred :: Exp Word16 -> Exp Word16
pred      = Exp Word16 -> Exp Word16
forall a. Num a => Exp a -> Exp a
defaultPred
  toEnum :: Int -> Exp Word16
toEnum    = Int -> Exp Word16
forall a. Int -> a
defaultToEnum
  fromEnum :: Exp Word16 -> Int
fromEnum  = Exp Word16 -> Int
forall a. a -> Int
defaultFromEnum

instance P.Enum (Exp Word32) where
  succ :: Exp Word32 -> Exp Word32
succ      = Exp Word32 -> Exp Word32
forall a. Num a => Exp a -> Exp a
defaultSucc
  pred :: Exp Word32 -> Exp Word32
pred      = Exp Word32 -> Exp Word32
forall a. Num a => Exp a -> Exp a
defaultPred
  toEnum :: Int -> Exp Word32
toEnum    = Int -> Exp Word32
forall a. Int -> a
defaultToEnum
  fromEnum :: Exp Word32 -> Int
fromEnum  = Exp Word32 -> Int
forall a. a -> Int
defaultFromEnum

instance P.Enum (Exp Word64) where
  succ :: Exp Word64 -> Exp Word64
succ      = Exp Word64 -> Exp Word64
forall a. Num a => Exp a -> Exp a
defaultSucc
  pred :: Exp Word64 -> Exp Word64
pred      = Exp Word64 -> Exp Word64
forall a. Num a => Exp a -> Exp a
defaultPred
  toEnum :: Int -> Exp Word64
toEnum    = Int -> Exp Word64
forall a. Int -> a
defaultToEnum
  fromEnum :: Exp Word64 -> Int
fromEnum  = Exp Word64 -> Int
forall a. a -> Int
defaultFromEnum

instance P.Enum (Exp CInt) where
  succ :: Exp CInt -> Exp CInt
succ      = Exp CInt -> Exp CInt
forall a. Num a => Exp a -> Exp a
defaultSucc
  pred :: Exp CInt -> Exp CInt
pred      = Exp CInt -> Exp CInt
forall a. Num a => Exp a -> Exp a
defaultPred
  toEnum :: Int -> Exp CInt
toEnum    = Int -> Exp CInt
forall a. Int -> a
defaultToEnum
  fromEnum :: Exp CInt -> Int
fromEnum  = Exp CInt -> Int
forall a. a -> Int
defaultFromEnum

instance P.Enum (Exp CUInt) where
  succ :: Exp CUInt -> Exp CUInt
succ      = Exp CUInt -> Exp CUInt
forall a. Num a => Exp a -> Exp a
defaultSucc
  pred :: Exp CUInt -> Exp CUInt
pred      = Exp CUInt -> Exp CUInt
forall a. Num a => Exp a -> Exp a
defaultPred
  toEnum :: Int -> Exp CUInt
toEnum    = Int -> Exp CUInt
forall a. Int -> a
defaultToEnum
  fromEnum :: Exp CUInt -> Int
fromEnum  = Exp CUInt -> Int
forall a. a -> Int
defaultFromEnum

instance P.Enum (Exp CLong) where
  succ :: Exp CLong -> Exp CLong
succ      = Exp CLong -> Exp CLong
forall a. Num a => Exp a -> Exp a
defaultSucc
  pred :: Exp CLong -> Exp CLong
pred      = Exp CLong -> Exp CLong
forall a. Num a => Exp a -> Exp a
defaultPred
  toEnum :: Int -> Exp CLong
toEnum    = Int -> Exp CLong
forall a. Int -> a
defaultToEnum
  fromEnum :: Exp CLong -> Int
fromEnum  = Exp CLong -> Int
forall a. a -> Int
defaultFromEnum

instance P.Enum (Exp CULong) where
  succ :: Exp CULong -> Exp CULong
succ      = Exp CULong -> Exp CULong
forall a. Num a => Exp a -> Exp a
defaultSucc
  pred :: Exp CULong -> Exp CULong
pred      = Exp CULong -> Exp CULong
forall a. Num a => Exp a -> Exp a
defaultPred
  toEnum :: Int -> Exp CULong
toEnum    = Int -> Exp CULong
forall a. Int -> a
defaultToEnum
  fromEnum :: Exp CULong -> Int
fromEnum  = Exp CULong -> Int
forall a. a -> Int
defaultFromEnum

instance P.Enum (Exp CLLong) where
  succ :: Exp CLLong -> Exp CLLong
succ      = Exp CLLong -> Exp CLLong
forall a. Num a => Exp a -> Exp a
defaultSucc
  pred :: Exp CLLong -> Exp CLLong
pred      = Exp CLLong -> Exp CLLong
forall a. Num a => Exp a -> Exp a
defaultPred
  toEnum :: Int -> Exp CLLong
toEnum    = Int -> Exp CLLong
forall a. Int -> a
defaultToEnum
  fromEnum :: Exp CLLong -> Int
fromEnum  = Exp CLLong -> Int
forall a. a -> Int
defaultFromEnum

instance P.Enum (Exp CULLong) where
  succ :: Exp CULLong -> Exp CULLong
succ      = Exp CULLong -> Exp CULLong
forall a. Num a => Exp a -> Exp a
defaultSucc
  pred :: Exp CULLong -> Exp CULLong
pred      = Exp CULLong -> Exp CULLong
forall a. Num a => Exp a -> Exp a
defaultPred
  toEnum :: Int -> Exp CULLong
toEnum    = Int -> Exp CULLong
forall a. Int -> a
defaultToEnum
  fromEnum :: Exp CULLong -> Int
fromEnum  = Exp CULLong -> Int
forall a. a -> Int
defaultFromEnum

instance P.Enum (Exp CShort) where
  succ :: Exp CShort -> Exp CShort
succ      = Exp CShort -> Exp CShort
forall a. Num a => Exp a -> Exp a
defaultSucc
  pred :: Exp CShort -> Exp CShort
pred      = Exp CShort -> Exp CShort
forall a. Num a => Exp a -> Exp a
defaultPred
  toEnum :: Int -> Exp CShort
toEnum    = Int -> Exp CShort
forall a. Int -> a
defaultToEnum
  fromEnum :: Exp CShort -> Int
fromEnum  = Exp CShort -> Int
forall a. a -> Int
defaultFromEnum

instance P.Enum (Exp CUShort) where
  succ :: Exp CUShort -> Exp CUShort
succ      = Exp CUShort -> Exp CUShort
forall a. Num a => Exp a -> Exp a
defaultSucc
  pred :: Exp CUShort -> Exp CUShort
pred      = Exp CUShort -> Exp CUShort
forall a. Num a => Exp a -> Exp a
defaultPred
  toEnum :: Int -> Exp CUShort
toEnum    = Int -> Exp CUShort
forall a. Int -> a
defaultToEnum
  fromEnum :: Exp CUShort -> Int
fromEnum  = Exp CUShort -> Int
forall a. a -> Int
defaultFromEnum

instance P.Enum (Exp Half) where
  succ :: Exp Half -> Exp Half
succ      = Exp Half -> Exp Half
forall a. Num a => Exp a -> Exp a
defaultSucc
  pred :: Exp Half -> Exp Half
pred      = Exp Half -> Exp Half
forall a. Num a => Exp a -> Exp a
defaultPred
  toEnum :: Int -> Exp Half
toEnum    = Int -> Exp Half
forall a. Int -> a
defaultToEnum
  fromEnum :: Exp Half -> Int
fromEnum  = Exp Half -> Int
forall a. a -> Int
defaultFromEnum

instance P.Enum (Exp Float) where
  succ :: Exp Float -> Exp Float
succ      = Exp Float -> Exp Float
forall a. Num a => Exp a -> Exp a
defaultSucc
  pred :: Exp Float -> Exp Float
pred      = Exp Float -> Exp Float
forall a. Num a => Exp a -> Exp a
defaultPred
  toEnum :: Int -> Exp Float
toEnum    = Int -> Exp Float
forall a. Int -> a
defaultToEnum
  fromEnum :: Exp Float -> Int
fromEnum  = Exp Float -> Int
forall a. a -> Int
defaultFromEnum

instance P.Enum (Exp Double) where
  succ :: Exp Double -> Exp Double
succ      = Exp Double -> Exp Double
forall a. Num a => Exp a -> Exp a
defaultSucc
  pred :: Exp Double -> Exp Double
pred      = Exp Double -> Exp Double
forall a. Num a => Exp a -> Exp a
defaultPred
  toEnum :: Int -> Exp Double
toEnum    = Int -> Exp Double
forall a. Int -> a
defaultToEnum
  fromEnum :: Exp Double -> Int
fromEnum  = Exp Double -> Int
forall a. a -> Int
defaultFromEnum

instance P.Enum (Exp CFloat) where
  succ :: Exp CFloat -> Exp CFloat
succ      = Exp CFloat -> Exp CFloat
forall a. Num a => Exp a -> Exp a
defaultSucc
  pred :: Exp CFloat -> Exp CFloat
pred      = Exp CFloat -> Exp CFloat
forall a. Num a => Exp a -> Exp a
defaultPred
  toEnum :: Int -> Exp CFloat
toEnum    = Int -> Exp CFloat
forall a. Int -> a
defaultToEnum
  fromEnum :: Exp CFloat -> Int
fromEnum  = Exp CFloat -> Int
forall a. a -> Int
defaultFromEnum

instance P.Enum (Exp CDouble) where
  succ :: Exp CDouble -> Exp CDouble
succ      = Exp CDouble -> Exp CDouble
forall a. Num a => Exp a -> Exp a
defaultSucc
  pred :: Exp CDouble -> Exp CDouble
pred      = Exp CDouble -> Exp CDouble
forall a. Num a => Exp a -> Exp a
defaultPred
  toEnum :: Int -> Exp CDouble
toEnum    = Int -> Exp CDouble
forall a. Int -> a
defaultToEnum
  fromEnum :: Exp CDouble -> Int
fromEnum  = Exp CDouble -> Int
forall a. a -> Int
defaultFromEnum

defaultSucc :: Num a => Exp a -> Exp a
defaultSucc :: Exp a -> Exp a
defaultSucc Exp a
x = Exp a
x Exp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
+ Exp a
1

defaultPred :: Num a => Exp a -> Exp a
defaultPred :: Exp a -> Exp a
defaultPred Exp a
x = Exp a
x Exp a -> Exp a -> Exp a
forall a. Num a => a -> a -> a
- Exp a
1

defaultToEnum :: Int -> a
defaultToEnum :: Int -> a
defaultToEnum = String -> Int -> a
forall a. String -> a
preludeError String
"toEnum"

defaultFromEnum :: a -> Int
defaultFromEnum :: a -> Int
defaultFromEnum = String -> a -> Int
forall a. String -> a
preludeError String
"fromEnum"

preludeError :: String -> a
preludeError :: String -> a
preludeError String
x
  = String -> a
forall a. HasCallStack => String -> a
error
  (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines [ String -> String -> String
forall r. PrintfType r => String -> r
printf String
"Prelude.%s is not supported for Accelerate types" String
x
            , String
""
            , String
"These Prelude.Enum instances are present only to fulfil superclass"
            , String
"constraints for subsequent classes in the standard Haskell numeric hierarchy."
            ]