{-# LANGUAGE TypeFamilies, FlexibleInstances #-}
module Data.NetCDF.Utils where
import Data.NetCDF.Raw
import Data.NetCDF.Types
import Control.Monad.Trans.Class
import Control.Monad.IO.Class
import Control.Monad.Trans.Reader
import Control.Monad.Trans.Except
type NcIO a = IO (Either NcError a)
type Access a = ReaderT (String, FilePath) (ExceptT NcError IO) a
runAccess :: String -> String -> Access a -> NcIO a
runAccess f p = runExceptT . flip runReaderT (f, p)
class Checkable a where
type OutType a :: *
status :: a -> Int
proj :: a -> OutType a
instance Checkable Int where
type OutType Int = ()
status s = s
proj _ = ()
instance Checkable (Int, a) where
type OutType (Int, a) = a
status (s, _) = s
proj (_, a) = a
instance Checkable (Int, a, b) where
type OutType (Int, a, b) = (a, b)
status (s, _, _) = s
proj (_, a, b) = (a, b)
instance Checkable (Int, a, b, c) where
type OutType (Int, a, b, c) = (a, b, c)
status (s, _, _, _) = s
proj (_, a, b, c) = (a, b, c)
instance Checkable (Int, a, b, c, d) where
type OutType (Int, a, b, c, d) = (a, b, c, d)
status (s, _, _, _, _) = s
proj (_, a, b, c, d) = (a, b, c, d)
instance Checkable (Int, a, b, c, d, e) where
type OutType (Int, a, b, c, d, e) = (a, b, c, d, e)
status (s, _, _, _, _, _) = s
proj (_, a, b, c, d, e) = (a, b, c, d, e)
chk :: Checkable a => IO a -> Access (OutType a)
chk act = do
res <- lift $ liftIO $ act
let st = status res
val = proj res
(f, p) <- ask
lift $ if st == 0
then ExceptT (return $ Right val)
else ExceptT (return $ Left $ NcError f st (nc_strerror st) p)