isotope-0.5.0.0: src/Isotope/Ion.hs
{-|
Module : Isotope.Ion
Description : Provides support for ions.
Copyright : Michael Thomas
License : GPL-3
Maintainer : Michael Thomas <Michaelt293@gmail.com>
Stability : Experimental
This module allows the mass-to-charge ratio and polarity of ions to be
calculated.
-}
module Isotope.Ion where
import Isotope.Base
import Data.Maybe (fromMaybe)
import Data.Monoid
-- | The polarity of a charge. A charge can be either `Positive` or `Negative`.
data Polarity = Positive | Negative
deriving (Show, Read, Eq, Ord)
-- | The mass-to-charge ratio of an ion.
newtype Mz = Mz { getMz :: Double }
deriving (Show, Read, Eq, Ord)
-- | The `Ion` type class. This type class has two methods: `mz` and `polarity`.
class ToElementalComposition a => Ion a where
mz :: a -> Mz
polarity :: a -> Polarity
mz a = Mz . abs $ monoisotopicMass' / charge'
where
monoisotopicMass' = getMonoisotopicMass $ monoisotopicMass a
charge' = let charge'' = fromMaybe 0 (charge a)
in if charge'' /= 0
then fromIntegral charge''
else error "An ion can't have a charge of 0!"
polarity a = polarity' $ fromMaybe 0 (charge a)
where
polarity' c
| c > 0 = Positive
| c < 0 = Negative
| c == 0 = error "An ion can't have a charge of 0!"
-- | Protonated represents a protonated ion.
newtype Protonated a = Protonated a deriving (Show, Read, Eq, Ord)
instance ToElementalComposition a => ToElementalComposition (Protonated a) where
toElementalComposition (Protonated a) = toElementalComposition a |+|
mkElementalComposition [(H, 1)]
charge (Protonated a) = getSum <$> Just (Sum 1) <> (Sum <$> charge a)
instance ToElementalComposition a => Ion (Protonated a)
-- | `doublyProtonated` takes a type and returns a doubly `Protonated` ion.
doublyProtonated :: a -> Protonated (Protonated a)
doublyProtonated = Protonated . Protonated
-- | `Deprotonated` represents a deprotonated ion.
newtype Deprotonated a = Deprotonated a deriving (Show, Read, Eq, Ord)
instance ToElementalComposition a => ToElementalComposition (Deprotonated a) where
toElementalComposition (Deprotonated a) = toElementalComposition a |-|
mkElementalComposition [(H, 1)]
charge (Deprotonated a) = getSum <$> Just (Sum (-1)) <> (Sum <$> charge a)
instance ToElementalComposition a => Ion (Deprotonated a)
-- | `doublyDeprotonated` takes a type and returns a doubly `Deprotonated` ion.
doublyDeprotonated :: a -> Deprotonated (Deprotonated a)
doublyDeprotonated = Deprotonated . Deprotonated