{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE DataKinds #-}
signature Torch.Sig.Types where

import Foreign
import Foreign.Storable
import GHC.TypeLits (Nat)
import Torch.Sig.Types.Global as X
import Control.DeepSeq
import Text.Printf

-- all C-types
data CTensor
instance Eq CTensor
data CStorage
instance Eq CStorage

-- freeStorage :: Ptr CState -> Ptr CStorage -> IO ()
-- freeTensor  :: Ptr CState -> Ptr CTensor -> IO ()

-- all haskell, memory-managed types
data Dynamic
instance Eq Dynamic
ctensor         :: Dynamic -> ForeignPtr CTensor
dynamic         :: ForeignPtr CState -> ForeignPtr CTensor -> Dynamic
dynamicState    :: Dynamic -> (ForeignPtr CState, ForeignPtr CTensor)
dynamicStateRef :: Dynamic -> ForeignPtr CState

data Storage
instance Eq Storage
cstorage        :: Storage -> ForeignPtr CStorage
storage         :: ForeignPtr CState -> ForeignPtr CStorage -> Storage
storageState    :: Storage -> (ForeignPtr CState, ForeignPtr CStorage)
storageStateRef :: Storage -> ForeignPtr CState

data Tensor (d::[Nat])
instance Eq (Tensor d)
asStatic  :: Dynamic -> Tensor d
asDynamic :: Tensor d -> Dynamic

data CReal
instance Num  CReal
instance Show CReal
instance Storable CReal
instance NFData CReal
-- instance PrintfArg CReal

data CAccReal
instance Num  CAccReal
instance Show CAccReal
instance Storable CAccReal
instance NFData CAccReal
-- instance PrintfArg CAccReal

data HsReal
instance Num  HsReal
instance Show HsReal
instance Ord HsReal
instance NFData HsReal
instance PrintfArg HsReal

-- FIXME: Consider how we will add things that are Fractional-specific in the
-- NN package like xavier instantiation.
--
-- instance Fractional HsReal

data HsAccReal
instance Num  HsAccReal
instance Show HsAccReal
instance Ord HsAccReal
instance NFData HsAccReal
instance PrintfArg HsAccReal

real2acc :: HsReal -> HsAccReal
acc2real :: HsAccReal -> HsReal

hs2cReal :: HsReal -> CReal
hs2cAccReal :: HsAccReal -> CAccReal

c2hsReal :: CReal -> HsReal
c2hsAccReal :: CAccReal -> HsAccReal

-- i2hsReal :: Integral i => i -> HsReal