{-|
Module      : SimFin.Types.Industry
Description : Parameterized sum type to distinguish between different industry specific data.
Copyright   : (c) Owen Shepherd, 2022
License     : MIT
Maintainer  : owen@owen.cafe
-}

module SimFin.Types.Industry
  ( Industry(..)
  , mapIndustry
  , invertIndustries
  ) where

import Data.Foldable

-- | Distinguish between different industry-specific data.

data Industry general bank insurance
  = General general
  | Bank bank
  | Insurance insurance
  deriving Int -> Industry general bank insurance -> ShowS
[Industry general bank insurance] -> ShowS
Industry general bank insurance -> String
(Int -> Industry general bank insurance -> ShowS)
-> (Industry general bank insurance -> String)
-> ([Industry general bank insurance] -> ShowS)
-> Show (Industry general bank insurance)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall general bank insurance.
(Show general, Show bank, Show insurance) =>
Int -> Industry general bank insurance -> ShowS
forall general bank insurance.
(Show general, Show bank, Show insurance) =>
[Industry general bank insurance] -> ShowS
forall general bank insurance.
(Show general, Show bank, Show insurance) =>
Industry general bank insurance -> String
showList :: [Industry general bank insurance] -> ShowS
$cshowList :: forall general bank insurance.
(Show general, Show bank, Show insurance) =>
[Industry general bank insurance] -> ShowS
show :: Industry general bank insurance -> String
$cshow :: forall general bank insurance.
(Show general, Show bank, Show insurance) =>
Industry general bank insurance -> String
showsPrec :: Int -> Industry general bank insurance -> ShowS
$cshowsPrec :: forall general bank insurance.
(Show general, Show bank, Show insurance) =>
Int -> Industry general bank insurance -> ShowS
Show

-- | Map all discriminations of an Industry.

mapIndustry :: (a -> a') -> (b -> b') -> (c -> c') -> Industry a b c -> Industry a' b' c'
mapIndustry :: (a -> a')
-> (b -> b') -> (c -> c') -> Industry a b c -> Industry a' b' c'
mapIndustry a -> a'
f b -> b'
g c -> c'
h Industry a b c
industry = case Industry a b c
industry of
  General a
a -> a' -> Industry a' b' c'
forall general bank insurance.
general -> Industry general bank insurance
General (a' -> Industry a' b' c') -> a' -> Industry a' b' c'
forall a b. (a -> b) -> a -> b
$ a -> a'
f a
a
  Bank b
a -> b' -> Industry a' b' c'
forall general bank insurance.
bank -> Industry general bank insurance
Bank (b' -> Industry a' b' c') -> b' -> Industry a' b' c'
forall a b. (a -> b) -> a -> b
$ b -> b'
g b
a
  Insurance c
a -> c' -> Industry a' b' c'
forall general bank insurance.
insurance -> Industry general bank insurance
Insurance (c' -> Industry a' b' c') -> c' -> Industry a' b' c'
forall a b. (a -> b) -> a -> b
$ c -> c'
h c
a

invertIndustry :: Industry [a] [b] [c] -> [Industry a b c]
invertIndustry :: Industry [a] [b] [c] -> [Industry a b c]
invertIndustry Industry [a] [b] [c]
ind = case Industry [a] [b] [c]
ind of
  General [a]
as -> a -> Industry a b c
forall general bank insurance.
general -> Industry general bank insurance
General (a -> Industry a b c) -> [a] -> [Industry a b c]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [a]
as
  Bank [b]
bs -> b -> Industry a b c
forall general bank insurance.
bank -> Industry general bank insurance
Bank (b -> Industry a b c) -> [b] -> [Industry a b c]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [b]
bs
  Insurance [c]
cs -> c -> Industry a b c
forall general bank insurance.
insurance -> Industry general bank insurance
Insurance (c -> Industry a b c) -> [c] -> [Industry a b c]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [c]
cs

-- | List of discriminations of lists to list of discriminations.
-- Used to removing extra nesting from the statements API results.

invertIndustries :: [Industry [a] [b] [c]] -> [Industry a b c]
invertIndustries :: [Industry [a] [b] [c]] -> [Industry a b c]
invertIndustries = [[Industry a b c]] -> [Industry a b c]
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold ([[Industry a b c]] -> [Industry a b c])
-> ([Industry [a] [b] [c]] -> [[Industry a b c]])
-> [Industry [a] [b] [c]]
-> [Industry a b c]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Industry [a] [b] [c] -> [Industry a b c])
-> [Industry [a] [b] [c]] -> [[Industry a b c]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Industry [a] [b] [c] -> [Industry a b c]
forall a b c. Industry [a] [b] [c] -> [Industry a b c]
invertIndustry