packages feed

api-monobank 0.1.0.0 → 0.1.0.1

raw patch · 8 files changed

+208/−210 lines, 8 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Api: getCurrencies :: IO [CurrencyPair]
- Api: getPersonalInfo :: () => a
- Api: getPersonalStatement :: () => a
- Api: getPersonalStatementFull :: () => a
- Types: Account :: Text -> Int -> Int -> Currency -> Text -> Account
- Types: Currency :: String -> Int -> Int -> String -> String -> Currency
- Types: CurrencyPair :: Currency -> Currency -> Int -> Maybe Float -> Maybe Float -> Maybe Float -> CurrencyPair
- Types: Statement :: String -> String -> String -> String -> Bool -> Int -> Int -> Currency -> Int -> Int -> Int -> Statement
- Types: User :: String -> [Account] -> User
- Types: [acBalance] :: Account -> Int
- Types: [acCashbackType] :: Account -> Text
- Types: [acCreditLimit] :: Account -> Int
- Types: [acCurrency] :: Account -> Currency
- Types: [acId] :: Account -> Text
- Types: [balance] :: Statement -> Int
- Types: [cpCurrencyCodeA] :: CurrencyPair -> Currency
- Types: [cpCurrencyCodeB] :: CurrencyPair -> Currency
- Types: [cpDate] :: CurrencyPair -> Int
- Types: [cpRateBuy] :: CurrencyPair -> Maybe Float
- Types: [cpRateCross] :: CurrencyPair -> Maybe Float
- Types: [cpRateSell] :: CurrencyPair -> Maybe Float
- Types: [decimalDigits] :: Currency -> Int
- Types: [isoCode] :: Currency -> String
- Types: [isoNumericCode] :: Currency -> Int
- Types: [name] :: Currency -> String
- Types: [stAmount] :: Statement -> Int
- Types: [stCashbackAmount] :: Statement -> Int
- Types: [stComissionRate] :: Statement -> Int
- Types: [stCurrency] :: Statement -> Currency
- Types: [stDescription] :: Statement -> String
- Types: [stHold] :: Statement -> Bool
- Types: [stId] :: Statement -> String
- Types: [stMCC] :: Statement -> String
- Types: [stOperationAmount] :: Statement -> Int
- Types: [stTime] :: Statement -> String
- Types: [symbol] :: Currency -> String
- Types: [uAccounts] :: User -> [Account]
- Types: [uName] :: User -> String
- Types: convertCurrencyFromCode :: Int -> Currency
- Types: data Account
- Types: data Currency
- Types: data CurrencyPair
- Types: data Statement
- Types: data User
- Types: instance Data.Aeson.Types.FromJSON.FromJSON Types.CurrencyPair
- Types: instance GHC.Classes.Eq Types.Account
- Types: instance GHC.Classes.Eq Types.Currency
- Types: instance GHC.Classes.Eq Types.Statement
- Types: instance GHC.Classes.Eq Types.User
- Types: instance GHC.Show.Show Types.Account
- Types: instance GHC.Show.Show Types.Currency
- Types: instance GHC.Show.Show Types.CurrencyPair
- Types: instance GHC.Show.Show Types.Statement
- Types: instance GHC.Show.Show Types.User
- Types: showCurrencyPair :: CurrencyPair -> IO ()
- Types: type Token = Text
- Utils: uncapFst :: String -> String
+ Monobank.Api: getCurrencies :: IO [CurrencyPair]
+ Monobank.Api: getPersonalInfo :: () => a
+ Monobank.Api: getPersonalStatement :: () => a
+ Monobank.Api: getPersonalStatementFull :: () => a
+ Monobank.Types: Account :: Text -> Int -> Int -> Currency -> Text -> Account
+ Monobank.Types: Currency :: String -> Int -> Int -> String -> String -> Currency
+ Monobank.Types: CurrencyPair :: Currency -> Currency -> Int -> Maybe Float -> Maybe Float -> Maybe Float -> CurrencyPair
+ Monobank.Types: Statement :: String -> String -> String -> String -> Bool -> Int -> Int -> Currency -> Int -> Int -> Int -> Statement
+ Monobank.Types: User :: String -> [Account] -> User
+ Monobank.Types: [acBalance] :: Account -> Int
+ Monobank.Types: [acCashbackType] :: Account -> Text
+ Monobank.Types: [acCreditLimit] :: Account -> Int
+ Monobank.Types: [acCurrency] :: Account -> Currency
+ Monobank.Types: [acId] :: Account -> Text
+ Monobank.Types: [balance] :: Statement -> Int
+ Monobank.Types: [cpCurrencyCodeA] :: CurrencyPair -> Currency
+ Monobank.Types: [cpCurrencyCodeB] :: CurrencyPair -> Currency
+ Monobank.Types: [cpDate] :: CurrencyPair -> Int
+ Monobank.Types: [cpRateBuy] :: CurrencyPair -> Maybe Float
+ Monobank.Types: [cpRateCross] :: CurrencyPair -> Maybe Float
+ Monobank.Types: [cpRateSell] :: CurrencyPair -> Maybe Float
+ Monobank.Types: [decimalDigits] :: Currency -> Int
+ Monobank.Types: [isoCode] :: Currency -> String
+ Monobank.Types: [isoNumericCode] :: Currency -> Int
+ Monobank.Types: [name] :: Currency -> String
+ Monobank.Types: [stAmount] :: Statement -> Int
+ Monobank.Types: [stCashbackAmount] :: Statement -> Int
+ Monobank.Types: [stComissionRate] :: Statement -> Int
+ Monobank.Types: [stCurrency] :: Statement -> Currency
+ Monobank.Types: [stDescription] :: Statement -> String
+ Monobank.Types: [stHold] :: Statement -> Bool
+ Monobank.Types: [stId] :: Statement -> String
+ Monobank.Types: [stMCC] :: Statement -> String
+ Monobank.Types: [stOperationAmount] :: Statement -> Int
+ Monobank.Types: [stTime] :: Statement -> String
+ Monobank.Types: [symbol] :: Currency -> String
+ Monobank.Types: [uAccounts] :: User -> [Account]
+ Monobank.Types: [uName] :: User -> String
+ Monobank.Types: convertCurrencyFromCode :: Int -> Currency
+ Monobank.Types: data Account
+ Monobank.Types: data Currency
+ Monobank.Types: data CurrencyPair
+ Monobank.Types: data Statement
+ Monobank.Types: data User
+ Monobank.Types: instance Data.Aeson.Types.FromJSON.FromJSON Monobank.Types.CurrencyPair
+ Monobank.Types: instance GHC.Classes.Eq Monobank.Types.Account
+ Monobank.Types: instance GHC.Classes.Eq Monobank.Types.Currency
+ Monobank.Types: instance GHC.Classes.Eq Monobank.Types.Statement
+ Monobank.Types: instance GHC.Classes.Eq Monobank.Types.User
+ Monobank.Types: instance GHC.Show.Show Monobank.Types.Account
+ Monobank.Types: instance GHC.Show.Show Monobank.Types.Currency
+ Monobank.Types: instance GHC.Show.Show Monobank.Types.CurrencyPair
+ Monobank.Types: instance GHC.Show.Show Monobank.Types.Statement
+ Monobank.Types: instance GHC.Show.Show Monobank.Types.User
+ Monobank.Types: showCurrencyPair :: CurrencyPair -> IO ()
+ Monobank.Types: type Token = Text
+ Monobank.Utils: uncapFst :: String -> String

Files

api-monobank.cabal view
@@ -1,5 +1,5 @@ name:                api-monobank-version:             0.1.0.0+version:             0.1.0.1 -- synopsis: description:         Api client for popular Ukrainian bank - Monobank homepage:            https://github.com/sigrlami/api-monobank#readme@@ -15,9 +15,9 @@  library   hs-source-dirs:      src-  exposed-modules:     Api-                     , Types-                     , Utils+  exposed-modules:     Monobank.Api+                     , Monobank.Types+                     , Monobank.Utils   build-depends:       base >= 4.7 && < 5                      , aeson                      , text
app/Main.hs view
@@ -9,8 +9,8 @@ import           Data.Time.Clock import           System.Environment -import qualified Api                         as MBApi-import qualified Types                       as MBApi+import qualified Monobank.Api                as MBApi+import qualified Monobank.Types              as MBApi  -------------------------------------------------------------------------------- 
− src/Api.hs
@@ -1,57 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}--module Api-    ( getCurrencies-    , getPersonalInfo-    , getPersonalStatement-    , getPersonalStatementFull-    ) where--import           Data.Aeson-import qualified Data.ByteString.Char8      as B-import qualified Data.ByteString.Lazy.Char8 as BL-import qualified Data.Text                  as T-import           Network.HTTP.Conduit       (simpleHttp)--import           Types-import           Utils-------------------------------------------------------------------------------------endpoint :: T.Text-endpoint = "https://api.monobank.ua"---- Get a basic list of monobank currency rates.--- Information is cached and updated no more than once every 5 minutes.------ GET /bank/currency-getCurrencies :: IO [CurrencyPair]-getCurrencies = do-  let path = T.concat [endpoint, "/bank/currency"]-  -- results <- fmap decodeEither $ simpleHttp (T.unpack path)-  resp <- simpleHttp (T.unpack path)-  --putStrLn $ show $ resp-  let res = eitherDecode resp-  case res of-    Left err  -> do-      putStrLn err-      return $ []-    Right val -> do-      return $ val---- GET /personal/client-info-getPersonalInfo = undefined----- Receive an extract for the time from {to} to {to} time in seconds Unix time format.--- The maximum time for which it is possible to extract an extract is 31 days--- (2678400 seconds) Limit on the use of the function no more than 1 time in 60 seconds.------ GET /personal/statement/{account}/{from}/{to}-getPersonalStatement = undefined----- Get Personal Statement from beginning--- 12 months will take 12 minutes-getPersonalStatementFull = undefined
+ src/Monobank/Api.hs view
@@ -0,0 +1,56 @@+{-# LANGUAGE OverloadedStrings #-}++module Monobank.Api+    ( getCurrencies+    , getPersonalInfo+    , getPersonalStatement+    , getPersonalStatementFull+    ) where++import           Data.Aeson+import qualified Data.ByteString.Char8      as B+import qualified Data.ByteString.Lazy.Char8 as BL+import qualified Data.Text                  as T+import           Network.HTTP.Conduit       (simpleHttp)++import           Monobank.Types+import           Monobank.Utils++--------------------------------------------------------------------------------++endpoint :: T.Text+endpoint = "https://api.monobank.ua"++-- Get a basic list of monobank currency rates.+-- Information is cached and updated no more than once every 5 minutes.+--+-- GET /bank/currency+getCurrencies :: IO [CurrencyPair]+getCurrencies = do+  let path = T.concat [endpoint, "/bank/currency"]+  -- results <- fmap decodeEither $ simpleHttp (T.unpack path)+  resp <- simpleHttp (T.unpack path)+  --putStrLn $ show $ resp+  let res = eitherDecode resp+  case res of+    Left err  -> do+      putStrLn err+      return $ []+    Right val -> do+      return $ val++-- GET /personal/client-info+getPersonalInfo = undefined+++-- Receive an extract for the time from {to} to {to} time in seconds Unix time format.+-- The maximum time for which it is possible to extract an extract is 31 days+-- (2678400 seconds) Limit on the use of the function no more than 1 time in 60 seconds.+--+-- GET /personal/statement/{account}/{from}/{to}+getPersonalStatement = undefined+++-- Get Personal Statement from beginning+-- 12 months will take 12 minutes+getPersonalStatementFull = undefined
+ src/Monobank/Types.hs view
@@ -0,0 +1,135 @@+{-# LANGUAGE DeriveAnyClass        #-}+{-# LANGUAGE DeriveGeneric         #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE GADTs                 #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings     #-}+{-# LANGUAGE TemplateHaskell       #-}+{-# LANGUAGE TypeSynonymInstances  #-}++module Monobank.Types where++import           Data.Aeson+import           Data.Aeson.TH+import           Data.Maybe+import qualified Data.Text      as T+import           Data.Time+import           GHC.Generics++import           Monobank.Utils++-----------------------------------------------------------------++-- | Wrapper for user token from Developer's Dashboard, https://api.monobank.ua/+type Token = T.Text++-----------------------------------------------------------------++data Currency =+  Currency+    { isoCode        :: String+    , isoNumericCode :: Int+    , decimalDigits  :: Int+    , symbol         :: String+    , name           :: String+    } deriving (Eq, Show)++convertCurrencyFromCode :: Int -> Currency+convertCurrencyFromCode val =+  case val of+    840       ->  Currency { isoCode = "USD", isoNumericCode=  840, decimalDigits= 2, symbol= "$", name="Dollar"}+    978       ->  Currency { isoCode = "EUR", isoNumericCode=  978, decimalDigits= 2, symbol= "€", name="Euro"}+    980       ->  Currency { isoCode = "UAH", isoNumericCode=  980, decimalDigits= 2, symbol= "₴", name="Hrivnya"}+    643       ->  Currency { isoCode = "RUB", isoNumericCode=  643, decimalDigits= 2, symbol= "", name="Ruble"}+    826       ->  Currency { isoCode = "GBP", isoNumericCode=  826, decimalDigits= 2, symbol= "", name="Pound Sterling"}+    949       ->  Currency { isoCode = "TRY", isoNumericCode=  949, decimalDigits= 2, symbol= "", name="Lira"}+    985       ->  Currency { isoCode = "PLN", isoNumericCode=  985, decimalDigits= 2, symbol= "", name="Zloty"}+    348       ->  Currency { isoCode = "HUF", isoNumericCode=  348, decimalDigits= 2, symbol= "", name="Forint"}+    208       ->  Currency { isoCode = "DKK", isoNumericCode=  208, decimalDigits= 2, symbol= "", name="Danish Krone"}+    203       ->  Currency { isoCode = "CZK", isoNumericCode=  203, decimalDigits= 2, symbol= "", name="Czech Koruna"}+    124       ->  Currency { isoCode = "CAD", isoNumericCode=  124, decimalDigits= 2, symbol= "", name="Canadian Dollar"}+    933       ->  Currency { isoCode = "BYN", isoNumericCode=  933, decimalDigits= 2, symbol= "", name="Belarussian Ruble"}+    756       ->  Currency { isoCode = "CHF", isoNumericCode=  756, decimalDigits= 2, symbol= "", name="Swiss Franc"}+    otherwise ->  Currency { isoCode = "NA" , isoNumericCode=  0  , decimalDigits= 2, symbol= "", name="Uknown"}++-------------------------------------------------------------------------------------------++-- | Data type that represents currency pair from Monobank+--   at spicific time+data CurrencyPair =+  CurrencyPair+    { cpCurrencyCodeA :: Currency      -- ^ Currency derived from international identificator+    , cpCurrencyCodeB :: Currency      -- ^ Currency derived from international identificator+    , cpDate          :: Int           -- ^ Timestamp for the currency pair information+    , cpRateSell      :: Maybe Float   -- ^ Rate to sell currency+    , cpRateBuy       :: Maybe Float   -- ^ Rate to buy currency+    , cpRateCross     :: Maybe Float   -- ^ Rate+    } deriving (Show)++instance FromJSON CurrencyPair where+  parseJSON =+    withObject "object" $ \o -> do+      currA'     <- o .:  "currencyCodeA"+      currB'     <- o .:  "currencyCodeB"+      date'      <- o .:  "date"         -- TODO: convert to UTCTime+      rateSell'  <- o .:? "rateSell"+      rateBuy'   <- o .:? "rateBuy"+      rateCross' <- o .:? "rateCross"++      let currA = convertCurrencyFromCode currA'+          currB = convertCurrencyFromCode currB'+          --date  =++      return $+        CurrencyPair currA currB date' rateSell' rateBuy' rateCross'++showCurrencyPair :: CurrencyPair -> IO ()+showCurrencyPair cp = do+  putStrLn $ (isoCode $ cpCurrencyCodeA cp) ++ "/" ++ (isoCode $ cpCurrencyCodeB cp)+  case (cpRateBuy cp) of+    Nothing  -> do+      putStrLn $ " - Cross: " ++ (show $ fromMaybe 0 $ cpRateCross cp) ++ (symbol $ cpCurrencyCodeB cp)+      putStrLn $ ""+    Just buy -> do+      putStrLn $ " - Buy:  " ++ (show $ buy) ++ " " ++ (symbol $ cpCurrencyCodeB cp)+      putStrLn $ " - Sell: " ++ (show $ fromMaybe 0 $ cpRateSell cp) ++ (symbol $ cpCurrencyCodeB cp)+      putStrLn $ ""++-- Simplified version for one-to-one conversion+--+-- instance FromJSON CurrencyPair where+--   parseJSON = genericParseJSON opts+--     where+--       opts = defaultOptions { fieldLabelModifier = uncapFst . drop 2}++--------------------------------------------------------------------------------++data Account =+  Account+    { acId           :: T.Text    -- ^+    , acBalance      :: Int       -- ^ Current balance+    , acCreditLimit  :: Int       -- ^ Current credit limit available to user+    , acCurrency     :: Currency  -- ^ Currency of the account+    , acCashbackType :: T.Text    -- ^+    } deriving (Eq, Show)++data User =+  User+    { uName     :: String    -- ^ User's full name+    , uAccounts :: [Account] -- ^ List of user accounts, by currency type+    } deriving (Eq, Show)++data Statement =+  Statement+    { stId              :: String   -- ^+    , stTime            :: String   -- ^+    , stDescription     :: String   -- ^+    , stMCC             :: String   -- ^+    , stHold            :: Bool     -- ^+    , stAmount          :: Int      -- ^+    , stOperationAmount :: Int      -- ^+    , stCurrency        :: Currency -- ^+    , stComissionRate   :: Int      -- ^+    , stCashbackAmount  :: Int      -- ^+    , balance           :: Int      -- ^+    } deriving (Eq, Show)
+ src/Monobank/Utils.hs view
@@ -0,0 +1,11 @@+module Monobank.Utils where+++import qualified Data.Char as Char+import           Data.Text as T++-------------------------------------------------------------------++uncapFst :: String -> String+uncapFst (head:tail) = Char.toLower head : tail+uncapFst []          = []
− src/Types.hs
@@ -1,135 +0,0 @@-{-# LANGUAGE DeriveAnyClass        #-}-{-# LANGUAGE DeriveGeneric         #-}-{-# LANGUAGE FlexibleInstances     #-}-{-# LANGUAGE GADTs                 #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE OverloadedStrings     #-}-{-# LANGUAGE TemplateHaskell       #-}-{-# LANGUAGE TypeSynonymInstances  #-}--module Types where--import           Data.Aeson-import           Data.Aeson.TH-import           Data.Maybe-import qualified Data.Text     as T-import           Data.Time-import           GHC.Generics--import           Utils----------------------------------------------------------------------- | Wrapper for user token from Developer's Dashboard, https://api.monobank.ua/-type Token = T.Text---------------------------------------------------------------------data Currency =-  Currency-    { isoCode        :: String-    , isoNumericCode :: Int-    , decimalDigits  :: Int-    , symbol         :: String-    , name           :: String-    } deriving (Eq, Show)--convertCurrencyFromCode :: Int -> Currency-convertCurrencyFromCode val =-  case val of-    840       ->  Currency { isoCode = "USD", isoNumericCode=  840, decimalDigits= 2, symbol= "$", name="Dollar"}-    978       ->  Currency { isoCode = "EUR", isoNumericCode=  978, decimalDigits= 2, symbol= "€", name="Euro"}-    980       ->  Currency { isoCode = "UAH", isoNumericCode=  980, decimalDigits= 2, symbol= "₴", name="Hrivnya"}-    643       ->  Currency { isoCode = "RUB", isoNumericCode=  643, decimalDigits= 2, symbol= "", name="Ruble"}-    826       ->  Currency { isoCode = "GBP", isoNumericCode=  826, decimalDigits= 2, symbol= "", name="Pound Sterling"}-    949       ->  Currency { isoCode = "TRY", isoNumericCode=  949, decimalDigits= 2, symbol= "", name="Lira"}-    985       ->  Currency { isoCode = "PLN", isoNumericCode=  985, decimalDigits= 2, symbol= "", name="Zloty"}-    348       ->  Currency { isoCode = "HUF", isoNumericCode=  348, decimalDigits= 2, symbol= "", name="Forint"}-    208       ->  Currency { isoCode = "DKK", isoNumericCode=  208, decimalDigits= 2, symbol= "", name="Danish Krone"}-    203       ->  Currency { isoCode = "CZK", isoNumericCode=  203, decimalDigits= 2, symbol= "", name="Czech Koruna"}-    124       ->  Currency { isoCode = "CAD", isoNumericCode=  124, decimalDigits= 2, symbol= "", name="Canadian Dollar"}-    933       ->  Currency { isoCode = "BYN", isoNumericCode=  933, decimalDigits= 2, symbol= "", name="Belarussian Ruble"}-    756       ->  Currency { isoCode = "CHF", isoNumericCode=  756, decimalDigits= 2, symbol= "", name="Swiss Franc"}-    otherwise ->  Currency { isoCode = "NA" , isoNumericCode=  0  , decimalDigits= 2, symbol= "", name="Uknown"}------------------------------------------------------------------------------------------------- | Data type that represents currency pair from Monobank---   at spicific time-data CurrencyPair =-  CurrencyPair-    { cpCurrencyCodeA :: Currency      -- ^ Currency derived from international identificator-    , cpCurrencyCodeB :: Currency      -- ^ Currency derived from international identificator-    , cpDate          :: Int           -- ^ Timestamp for the currency pair information-    , cpRateSell      :: Maybe Float   -- ^ Rate to sell currency-    , cpRateBuy       :: Maybe Float   -- ^ Rate to buy currency-    , cpRateCross     :: Maybe Float   -- ^ Rate-    } deriving (Show)--instance FromJSON CurrencyPair where-  parseJSON =-    withObject "object" $ \o -> do-      currA'     <- o .:  "currencyCodeA"-      currB'     <- o .:  "currencyCodeB"-      date'      <- o .:  "date"         -- TODO: convert to UTCTime-      rateSell'  <- o .:? "rateSell"-      rateBuy'   <- o .:? "rateBuy"-      rateCross' <- o .:? "rateCross"--      let currA = convertCurrencyFromCode currA'-          currB = convertCurrencyFromCode currB'-          --date  =--      return $-        CurrencyPair currA currB date' rateSell' rateBuy' rateCross'--showCurrencyPair :: CurrencyPair -> IO ()-showCurrencyPair cp = do-  putStrLn $ (isoCode $ cpCurrencyCodeA cp) ++ "/" ++ (isoCode $ cpCurrencyCodeB cp)-  case (cpRateBuy cp) of-    Nothing  -> do-      putStrLn $ " - Cross: " ++ (show $ fromMaybe 0 $ cpRateCross cp) ++ (symbol $ cpCurrencyCodeB cp)-      putStrLn $ ""-    Just buy -> do-      putStrLn $ " - Buy:  " ++ (show $ buy) ++ " " ++ (symbol $ cpCurrencyCodeB cp)-      putStrLn $ " - Sell: " ++ (show $ fromMaybe 0 $ cpRateSell cp) ++ (symbol $ cpCurrencyCodeB cp)-      putStrLn $ ""---- Simplified version for one-to-one conversion------ instance FromJSON CurrencyPair where---   parseJSON = genericParseJSON opts---     where---       opts = defaultOptions { fieldLabelModifier = uncapFst . drop 2}------------------------------------------------------------------------------------data Account =-  Account-    { acId           :: T.Text    -- ^-    , acBalance      :: Int       -- ^ Current balance-    , acCreditLimit  :: Int       -- ^ Current credit limit available to user-    , acCurrency     :: Currency  -- ^ Currency of the account-    , acCashbackType :: T.Text    -- ^-    } deriving (Eq, Show)--data User =-  User-    { uName     :: String    -- ^ User's full name-    , uAccounts :: [Account] -- ^ List of user accounts, by currency type-    } deriving (Eq, Show)--data Statement =-  Statement-    { stId              :: String   -- ^-    , stTime            :: String   -- ^-    , stDescription     :: String   -- ^-    , stMCC             :: String   -- ^-    , stHold            :: Bool     -- ^-    , stAmount          :: Int      -- ^-    , stOperationAmount :: Int      -- ^-    , stCurrency        :: Currency -- ^-    , stComissionRate   :: Int      -- ^-    , stCashbackAmount  :: Int      -- ^-    , balance           :: Int      -- ^-    } deriving (Eq, Show)
− src/Utils.hs
@@ -1,12 +0,0 @@-module Utils where---import qualified Data.Char as Char-import           Data.Text as T------------------------------------------------------------------------uncapFst :: String -> String-uncapFst (head:tail) = Char.toLower head : tail-uncapFst []          = []