```{- Types
by Gregory Schwartz

-- | Collects the functions pertaining to the types used in the program
-}

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

module Types where

-- Standard
import qualified Data.Map.Strict as Map
import qualified Data.Sequence as Seq

-- Cabal
import Data.Fasta.Text (FastaSequence)

newtype AA        = AA { unAA :: Char } deriving (Eq, Ord, Show, Read)
newtype Nuc       = Nuc Char deriving (Eq, Ord, Show, Read)
newtype Field     = Field Int deriving (Eq)
newtype Frequency = Frequency Double
deriving (Eq, Ord, Num, Enum, Show, Read, Fractional)
newtype Position  = Position Int deriving (Eq, Ord, Num, Enum, Show, Read)
newtype Identity  = Identity Double deriving (Eq, Ord, Num, Show, Read)
newtype BlosumVal = BlosumVal { unBlosumVal :: Int }
deriving (Eq, Ord, Num, Enum, Show, Read)

newtype ClusterMap          =
ClusterMap { unClusterMap :: Map.Map Int (Seq.Seq FastaSequence) }
deriving (Eq, Ord, Show)
newtype ClusterFrequencyMap =
ClusterFrequencyMap
{ unClusterFrequencyMap :: (Map.Map Position (Seq.Seq (AA, Frequency)))
}
deriving (Eq, Ord, Show)
newtype AAMap               = AAMap
{ unAAMap :: Map.Map AA (Map.Map AA Frequency) }
deriving (Eq, Ord, Show)
newtype BlockMap            = BlockMap { unBlockMap :: AAMap }
deriving (Eq, Ord, Show)
newtype FrequencyMap        = FrequencyMap { unFrequencyMap :: AAMap }
deriving (Eq, Ord, Show)
newtype Blosum              =
Blosum { unBlosum :: (Map.Map AA (Map.Map AA BlosumVal)) }
deriving (Eq, Ord, Show)

instance Monoid AAMap where
mempty                      = AAMap Map.empty
mappend (AAMap x) (AAMap y) = AAMap \$ Map.unionWith (Map.unionWith (+)) x y
```