-- | Biological classification of species.

module Biobase.Types.Taxonomy where

import Control.DeepSeq
import Data.Aeson
import Data.Binary
import Data.Hashable (Hashable, hashWithSalt)
import Data.Primitive.Types
import Data.Serialize
import Data.Text (Text)
import Data.Vector.Binary
import Data.Vector.Serialize
import Data.Vector.Unboxed.Deriving
import Data.Vector (Vector)
import GHC.Generics (Generic)

import Biobase.Types.Accession (Accession,Species)
import Biobase.Types.Names (SpeciesName, TaxonomicRank)



-- | Taxonomic classification. @Enum@ together with a final @Unknown@ is
-- somewhat fishy.
--
-- TODO What should the order be? Kingdom > Species or Kingdom < Species?

data Classification
  = Kingdom
  | Phylum
  | Class
  | Order
  | SubOrder
  | Family
  | Genus
  | Species
  | Unknown
  deriving (Classification -> Classification -> Bool
(Classification -> Classification -> Bool)
-> (Classification -> Classification -> Bool) -> Eq Classification
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Classification -> Classification -> Bool
$c/= :: Classification -> Classification -> Bool
== :: Classification -> Classification -> Bool
$c== :: Classification -> Classification -> Bool
Eq,Eq Classification
Eq Classification
-> (Classification -> Classification -> Ordering)
-> (Classification -> Classification -> Bool)
-> (Classification -> Classification -> Bool)
-> (Classification -> Classification -> Bool)
-> (Classification -> Classification -> Bool)
-> (Classification -> Classification -> Classification)
-> (Classification -> Classification -> Classification)
-> Ord Classification
Classification -> Classification -> Bool
Classification -> Classification -> Ordering
Classification -> Classification -> Classification
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Classification -> Classification -> Classification
$cmin :: Classification -> Classification -> Classification
max :: Classification -> Classification -> Classification
$cmax :: Classification -> Classification -> Classification
>= :: Classification -> Classification -> Bool
$c>= :: Classification -> Classification -> Bool
> :: Classification -> Classification -> Bool
$c> :: Classification -> Classification -> Bool
<= :: Classification -> Classification -> Bool
$c<= :: Classification -> Classification -> Bool
< :: Classification -> Classification -> Bool
$c< :: Classification -> Classification -> Bool
compare :: Classification -> Classification -> Ordering
$ccompare :: Classification -> Classification -> Ordering
$cp1Ord :: Eq Classification
Ord,ReadPrec [Classification]
ReadPrec Classification
Int -> ReadS Classification
ReadS [Classification]
(Int -> ReadS Classification)
-> ReadS [Classification]
-> ReadPrec Classification
-> ReadPrec [Classification]
-> Read Classification
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Classification]
$creadListPrec :: ReadPrec [Classification]
readPrec :: ReadPrec Classification
$creadPrec :: ReadPrec Classification
readList :: ReadS [Classification]
$creadList :: ReadS [Classification]
readsPrec :: Int -> ReadS Classification
$creadsPrec :: Int -> ReadS Classification
Read,Int -> Classification -> ShowS
[Classification] -> ShowS
Classification -> String
(Int -> Classification -> ShowS)
-> (Classification -> String)
-> ([Classification] -> ShowS)
-> Show Classification
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Classification] -> ShowS
$cshowList :: [Classification] -> ShowS
show :: Classification -> String
$cshow :: Classification -> String
showsPrec :: Int -> Classification -> ShowS
$cshowsPrec :: Int -> Classification -> ShowS
Show,Int -> Classification
Classification -> Int
Classification -> [Classification]
Classification -> Classification
Classification -> Classification -> [Classification]
Classification
-> Classification -> Classification -> [Classification]
(Classification -> Classification)
-> (Classification -> Classification)
-> (Int -> Classification)
-> (Classification -> Int)
-> (Classification -> [Classification])
-> (Classification -> Classification -> [Classification])
-> (Classification -> Classification -> [Classification])
-> (Classification
    -> Classification -> Classification -> [Classification])
-> Enum Classification
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: Classification
-> Classification -> Classification -> [Classification]
$cenumFromThenTo :: Classification
-> Classification -> Classification -> [Classification]
enumFromTo :: Classification -> Classification -> [Classification]
$cenumFromTo :: Classification -> Classification -> [Classification]
enumFromThen :: Classification -> Classification -> [Classification]
$cenumFromThen :: Classification -> Classification -> [Classification]
enumFrom :: Classification -> [Classification]
$cenumFrom :: Classification -> [Classification]
fromEnum :: Classification -> Int
$cfromEnum :: Classification -> Int
toEnum :: Int -> Classification
$ctoEnum :: Int -> Classification
pred :: Classification -> Classification
$cpred :: Classification -> Classification
succ :: Classification -> Classification
$csucc :: Classification -> Classification
Enum,(forall x. Classification -> Rep Classification x)
-> (forall x. Rep Classification x -> Classification)
-> Generic Classification
forall x. Rep Classification x -> Classification
forall x. Classification -> Rep Classification x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Classification x -> Classification
$cfrom :: forall x. Classification -> Rep Classification x
Generic)

instance Binary    Classification
instance FromJSON  Classification
instance Hashable  Classification
instance Serialize Classification
instance ToJSON    Classification
instance NFData    Classification

derivingUnbox "Classification"
  [t| Classification -> Int |] [| fromEnum |] [| toEnum |]



-- | A somewhat generic representation of a species within a taxonomic
-- context.

data Taxon = Taxon
  { Taxon -> SpeciesName
species         :: !SpeciesName                             -- ^ the full, formal name of a species
  , Taxon -> Accession Species
accession       :: !(Accession Species)                     -- ^ the accession for the species (or @""@ if unknown)
  , Taxon -> Vector (TaxonomicRank, Classification)
classification  :: !(Vector (TaxonomicRank,Classification)) -- ^ vector with classification information
  }
  deriving (Taxon -> Taxon -> Bool
(Taxon -> Taxon -> Bool) -> (Taxon -> Taxon -> Bool) -> Eq Taxon
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Taxon -> Taxon -> Bool
$c/= :: Taxon -> Taxon -> Bool
== :: Taxon -> Taxon -> Bool
$c== :: Taxon -> Taxon -> Bool
Eq,ReadPrec [Taxon]
ReadPrec Taxon
Int -> ReadS Taxon
ReadS [Taxon]
(Int -> ReadS Taxon)
-> ReadS [Taxon]
-> ReadPrec Taxon
-> ReadPrec [Taxon]
-> Read Taxon
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Taxon]
$creadListPrec :: ReadPrec [Taxon]
readPrec :: ReadPrec Taxon
$creadPrec :: ReadPrec Taxon
readList :: ReadS [Taxon]
$creadList :: ReadS [Taxon]
readsPrec :: Int -> ReadS Taxon
$creadsPrec :: Int -> ReadS Taxon
Read,Int -> Taxon -> ShowS
[Taxon] -> ShowS
Taxon -> String
(Int -> Taxon -> ShowS)
-> (Taxon -> String) -> ([Taxon] -> ShowS) -> Show Taxon
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Taxon] -> ShowS
$cshowList :: [Taxon] -> ShowS
show :: Taxon -> String
$cshow :: Taxon -> String
showsPrec :: Int -> Taxon -> ShowS
$cshowsPrec :: Int -> Taxon -> ShowS
Show,(forall x. Taxon -> Rep Taxon x)
-> (forall x. Rep Taxon x -> Taxon) -> Generic Taxon
forall x. Rep Taxon x -> Taxon
forall x. Taxon -> Rep Taxon x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Taxon x -> Taxon
$cfrom :: forall x. Taxon -> Rep Taxon x
Generic)

instance Binary    Taxon
instance FromJSON  Taxon
instance Serialize Taxon
instance ToJSON    Taxon
instance NFData    Taxon

instance Hashable Taxon where
  hashWithSalt :: Int -> Taxon -> Int
hashWithSalt Int
h (Taxon SpeciesName
s Accession Species
a Vector (TaxonomicRank, Classification)
_) = Int -> (SpeciesName, Accession Species) -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
h (SpeciesName
s,Accession Species
a)