{- Copyright (C) 2018 Johann Lee This fiel is part of HaskellFAI HaskellFAI is free software: you can redistribute it and/or modify it under the terms of the GNU Less General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Haskell is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warrenty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Less General Public License for more details. You should have received a copy of the GNU Less General Public License along with HaskellFAI. If not, see . -} {-| Module: Foreign.FAI.Types Description: The types and the class of FAI Copyright: (C) 2018 Johann Lee License: LGPL3 Maintainer: me@qinka.pro Stability: experimental Portability: unknown The types and the class of FAI. -} {-# LANGUAGE GADTs #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeFamilies #-} module Foreign.FAI.Types ( Pf , Buffer(..) , Context(..) , Accelerate(..) , FAI(..) , FAICopy(..) , FinalizerContextPtr , Storable(..) , Ptr , ForeignPtr , liftIO ) where import Control.Monad.IO.Class (MonadIO (..)) import Foreign.ForeignPtr import Foreign.Ptr import Foreign.Storable -- | Platform types type family Pf p t :: * -- | buffer hosted pointer and size data Buffer p a = Buffer { bufPtr :: {-# UNPACK #-} !(ForeignPtr (Pf p a)) -- ^ pointer , bufSize :: {-# UNPACK #-} !Int -- ^ number of size } deriving (Show, Eq) -- | Context of platform -- -- The Haskell GC can not guarantee that @Context p@ will be released after -- all the @Buffer p a@ is released. -- So the C implement at lower level need to make sure it. newtype Context p = Context { unContextPtr :: ForeignPtr (Context p) } deriving (Show, Eq) -- | Accelearate type. newtype Accelerate p a = Accelerate { doAccelerate :: Context p -> IO (a, Context p) } -- | Context concened finalizer type FinalizerContextPtr p a = Either (FinalizerEnvPtr (Context p) a) (FinalizerPtr a) -- | FAI interface class FAI p where faiMemAllocate :: Context p -- ^ Context -> Int -- ^ size -> IO (Ptr a) -- ^ Pointer faiMemRelease :: Context p -- ^ Context -> Ptr a -- ^ Pointer -> IO () faiMemReleaseP :: Context p -- ^ Context -> IO (FinalizerContextPtr p a) -- ^ pointer of the function -- of release the pointer -- | Copy data from platform @p1@ to platform @p2@. class (FAI p1, FAI p2) => FAICopy p1 p2 where faiMemCopy :: (Storable b, (Pf p1 a) ~ b, Storable c, (Pf p2 a) ~ c) => Buffer p2 a -- ^ Destination -> Buffer p1 a -- ^ Source -> IO () instance Functor (Accelerate p) where fmap f (Accelerate a) = Accelerate $ \c -> do (r,c') <- a c return (f r, c') instance Applicative (Accelerate p) where pure x = Accelerate $ \c -> return (x, c) (<*>) (Accelerate ff) (Accelerate fa) = Accelerate $ \c1 -> do (r1,c2) <- fa c1 (r2,c3) <- ff c2 return (r2 r1, c3) instance Monad (Accelerate p) where (>>=) (Accelerate a) mf = Accelerate $ \c1 -> do (r1, c2) <- a c1 let (Accelerate m) = mf r1 m c2 instance MonadIO (Accelerate p) where liftIO m = Accelerate $ \c -> (\r -> (r,c)) <$> m