{-# LANGUAGE OverloadedStrings #-} module E9571.ConfigReader ( loadConfig , loadConfigOrDie ) where import Data.Aeson (FromJSON(..), eitherDecode) import qualified Data.ByteString.Lazy as LBS import System.Directory (doesFileExist) loadConfig :: FromJSON a => IO (Either String a) loadConfig :: forall a. FromJSON a => IO (Either String a) loadConfig = do let path :: String path = String "config.json" Bool exists <- String -> IO Bool doesFileExist String path if Bool -> Bool not Bool exists then Either String a -> IO (Either String a) forall a. a -> IO a forall (m :: * -> *) a. Monad m => a -> m a return (Either String a -> IO (Either String a)) -> Either String a -> IO (Either String a) forall a b. (a -> b) -> a -> b $ String -> Either String a forall a b. a -> Either a b Left String "Error: config.json not found in current directory" else do ByteString bs <- String -> IO ByteString LBS.readFile String path Either String a -> IO (Either String a) forall a. a -> IO a forall (f :: * -> *) a. Applicative f => a -> f a pure (Either String a -> IO (Either String a)) -> Either String a -> IO (Either String a) forall a b. (a -> b) -> a -> b $ (String -> Either String a) -> (a -> Either String a) -> Either String a -> Either String a forall a c b. (a -> c) -> (b -> c) -> Either a b -> c either (String -> Either String a forall a b. a -> Either a b Left (String -> Either String a) -> (String -> String) -> String -> Either String a forall b c a. (b -> c) -> (a -> b) -> a -> c . (String "JSON parse error: " String -> String -> String forall a. [a] -> [a] -> [a] ++)) a -> Either String a forall a b. b -> Either a b Right (ByteString -> Either String a forall a. FromJSON a => ByteString -> Either String a eitherDecode ByteString bs) loadConfigOrDie :: FromJSON a => IO a loadConfigOrDie :: forall a. FromJSON a => IO a loadConfigOrDie = IO (Either String a) forall a. FromJSON a => IO (Either String a) loadConfig IO (Either String a) -> (Either String a -> IO a) -> IO a forall a b. IO a -> (a -> IO b) -> IO b forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b >>= (String -> IO a) -> (a -> IO a) -> Either String a -> IO a forall a c b. (a -> c) -> (b -> c) -> Either a b -> c either String -> IO a forall a. String -> IO a forall (m :: * -> *) a. MonadFail m => String -> m a fail a -> IO a forall a. a -> IO a forall (f :: * -> *) a. Applicative f => a -> f a pure