Hello community, here is the log from the commit of package ghc-isotope for openSUSE:Factory checked in at 2017-08-31 20:56:48 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ghc-isotope (Old) and /work/SRC/openSUSE:Factory/.ghc-isotope.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-isotope" Thu Aug 31 20:56:48 2017 rev:2 rq:513408 version:0.5.0.1 Changes: -------- --- /work/SRC/openSUSE:Factory/ghc-isotope/ghc-isotope.changes 2017-04-11 09:38:30.689459377 +0200 +++ /work/SRC/openSUSE:Factory/.ghc-isotope.new/ghc-isotope.changes 2017-08-31 20:56:49.936307676 +0200 @@ -1,0 +2,5 @@ +Thu Jul 27 14:06:43 UTC 2017 - psim...@suse.com + +- Update to version 0.5.0.1. + +------------------------------------------------------------------- Old: ---- isotope-0.4.0.0.tar.gz New: ---- isotope-0.5.0.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-isotope.spec ++++++ --- /var/tmp/diff_new_pack.PLp2z4/_old 2017-08-31 20:56:50.588216081 +0200 +++ /var/tmp/diff_new_pack.PLp2z4/_new 2017-08-31 20:56:50.596214957 +0200 @@ -19,7 +19,7 @@ %global pkg_name isotope %bcond_with tests Name: ghc-%{pkg_name} -Version: 0.4.0.0 +Version: 0.5.0.1 Release: 0 Summary: Isotopic masses and relative abundances License: GPL-3.0+ ++++++ isotope-0.4.0.0.tar.gz -> isotope-0.5.0.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isotope-0.4.0.0/README.md new/isotope-0.5.0.1/README.md --- old/isotope-0.4.0.0/README.md 2017-03-11 09:42:03.000000000 +0100 +++ new/isotope-0.5.0.1/README.md 2017-04-30 01:08:04.000000000 +0200 @@ -1,5 +1,5 @@ [![Build Status](https://travis-ci.org/Michaelt293/isotope.svg?branch=master)](https://travis-ci.org/Michaelt293/isotope) -[![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/Michaelt293/isotope) +[![Gitter](https://badges.gitter.im/Michaelt293/isotope.svg)](https://gitter.im/Michaelt293/isotope) ![alt tag](https://github.com/Michaelt293/isotope/blob/master/isotope_jpeg.jpg) @@ -13,6 +13,7 @@ * [ToElementalComposition type class](#elementalcomposition-type-class) * [Behaviour of ElementalComposition, MolecularFormula, CondensedFormula and EmpiricalFormula data types](#behaviour-of-elementalcomposition-molecularformula-condensedformula-and-empiricalformula-data-types) * [Additional functions accepting an ElementSymbol as input](#additional-functions-accepting-an-elementsymbol-as-input) + * [Representing ions in Isotope](#representing-ions-in-isotope) * [Comparison to other chemistry libraries](#comparison-to-other-chemistry-libraries) * [Radium](#radium) * [Ouch](#ouch) @@ -108,13 +109,13 @@ ### `ToElementalComposition` type class -`ToElementalComposition` is a superclass of `ToMolecularFormula`, `ToCondensedFormula` and `ToEmpiricalFormula`. In addition to the `toElementalComposition` method, the `ToElementalComposition` type class has three other methods; `monoisotopicMass`, `nominalMass` and `averageMass`. (`toElementalComposition` is the minimal complete definition.) `ElementSymbol`, `ElementalComposition`, `MolecularFormula`, `CondensedFormula` and `EmpiricalFormula` all have instances of `ToElementalComposition`. This provides a uniform approach to working with elements, elemental compositions, molecular formulae, condensed formulae and empirical formulae. +`ToElementalComposition` is a superclass of `ToMolecularFormula`, `ToCondensedFormula` and `ToEmpiricalFormula`. In addition to the `toElementalComposition` method, the `ToElementalComposition` type class has four other methods; `charge`, `monoisotopicMass`, `nominalMass` and `averageMass`. (`toElementalComposition` and `charge` is the minimal complete definition.) `ElementSymbol`, `ElementalComposition`, `MolecularFormula`, `CondensedFormula` and `EmpiricalFormula` all have instances of `ToElementalComposition`. This provides a uniform approach to working with elements, elemental compositions, molecular formulae, condensed formulae and empirical formulae. ```haskell ghci> nominalMass C NominalMass {getNominalMass = 12} ghci> averageMass [mol|CH4|] AverageMass {getAverageMass = 16.042498912958358} -ghci> monoisotopicMass [mol|N(CH3)3|] +ghci> monoisotopicMass [con|N(CH3)3|] MonoisotopicMass {getMonoisotopicMass = 59.073499294499996} ``` @@ -158,6 +159,36 @@ [IsotopicMass {getIsotopicMass = 45.95262772},IsotopicMass {getIsotopicMass = 46.95175879},IsotopicMass {getIsotopicMass = 47.94794198},IsotopicMass {getIsotopicMass = 48.94786568},IsotopicMass {getIsotopicMass = 49.94478689}] ``` +### Representing ions in Isotope + +Ions are represented in `Isotope` using the `Ion` type class. The `Ion` type class has two methods, `mz` and `polarity`; where `mz` is mass-to-charge ratio and `polarity` is either `Positive` or `Negative`. Any type with an `ToElementalComposition` instance can have an `Ion` instance if charge is not equal to zero. If charge is equal to zero, a runtime exception will occur! Ideally, the type system should be put better use to catch this error at compile-time. + +```haskell +data Ammonium = Ammonium deriving Show + +instance ToElementalComposition Ammonium where + toElementalComposition _ = mkElementalComposition [(N, 1), (H, 4)] + charge _ = Just 1 + +instance Ion Ammonium + +ghci> mz Ammonium +Mz {getMz = 18.03437413335} +``` + +`Protonated` and `Deprotonated` types, with `Ion` instances, are provided to represent protonated and deprotonated ions, respectively. + +```haskell +ghci> mz . Protonated $ mkMolecularFormula [(H, 2), (O, 1)] +Mz {getMz = 19.01838971626} +ghci> mz . Deprotonated $ mkMolecularFormula [(H, 2), (O, 1)] +Mz {getMz = 17.0027396518} +ghci> polarity . Protonated $ mkMolecularFormula [(H, 2), (O, 1)] +Positive +ghci> polarity . Deprotonated $ mkMolecularFormula [(H, 2), (O, 1)] +Negative +``` + ## Comparison to other chemistry libraries In addition to Isotope, there are two other open-source chemistry libraries written in Haskell; Radium [2] and Ouch [3]. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isotope-0.4.0.0/isotope.cabal new/isotope-0.5.0.1/isotope.cabal --- old/isotope-0.4.0.0/isotope.cabal 2017-03-11 09:41:07.000000000 +0100 +++ new/isotope-0.5.0.1/isotope.cabal 2017-04-30 01:07:25.000000000 +0200 @@ -1,5 +1,5 @@ name: isotope -version: 0.4.0.0 +version: 0.5.0.1 synopsis: Isotopic masses and relative abundances. description: Please see README.md homepage: https://github.com/Michaelt293/Element-isotopes/blob/master/README.md @@ -18,6 +18,7 @@ exposed-modules: Isotope , Isotope.Base , Isotope.Parsers + , Isotope.Ion build-depends: base >= 4.7 && < 5 , containers >= 0.5 && < 0.6 , megaparsec >= 5 && < 6 @@ -37,5 +38,6 @@ , megaparsec other-modules: Isotope.BaseSpec , Isotope.ParsersSpec + , Isotope.IonSpec ghc-options: -threaded -rtsopts -with-rtsopts=-N default-language: Haskell2010 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isotope-0.4.0.0/src/Isotope/Base.hs new/isotope-0.5.0.1/src/Isotope/Base.hs --- old/isotope-0.4.0.0/src/Isotope/Base.hs 2017-03-11 09:41:07.000000000 +0100 +++ new/isotope-0.5.0.1/src/Isotope/Base.hs 2017-04-29 12:29:38.000000000 +0200 @@ -189,6 +189,8 @@ -- neutron number) for an isotope. type MassNumber = Int +type Charge = Int + -------------------------------------------------------------------------------- -- 'Isotope' and 'Element' data types @@ -638,13 +640,14 @@ -- 'monoisotopicMass', 'nominalMass' and 'averageMass'. class ToElementalComposition a where toElementalComposition :: a -> ElementalComposition + charge :: a -> Maybe Charge monoisotopicMass :: a -> MonoisotopicMass nominalMass :: a -> NominalMass averageMass :: a -> AverageMass monoisotopicMass = getFormulaSum elementMonoisotopicMass nominalMass = getFormulaSum elementNominalMass averageMass = getFormulaSum elementAverageMass - {-# MINIMAL (toElementalComposition) #-} + {-# MINIMAL (toElementalComposition, charge) #-} -- Helper function for the calculating monoistopic masses, average mass and -- nominal masses for molecular formulae. @@ -672,9 +675,11 @@ instance ToElementalComposition ElementSymbol where toElementalComposition sym = mkElementalComposition [(sym, 1)] + charge _ = Nothing instance ToElementalComposition ElementalComposition where toElementalComposition = id + charge _ = Nothing instance Formula ElementalComposition where renderFormula f = foldMap renderFoldfunc @@ -742,6 +747,7 @@ instance ToElementalComposition MolecularFormula where toElementalComposition (MolecularFormula m) = ElementalComposition m + charge _ = Nothing instance Formula MolecularFormula where renderFormula f = foldMap renderFoldfunc @@ -766,6 +772,7 @@ instance ToElementalComposition CondensedFormula where toElementalComposition = ElementalComposition . getMolecularFormula . toMolecularFormula + charge _ = Nothing instance ToMolecularFormula CondensedFormula where toMolecularFormula c = foldMap foldFunc (getCondensedFormula c) @@ -814,6 +821,7 @@ instance ToElementalComposition EmpiricalFormula where toElementalComposition (EmpiricalFormula a) = ElementalComposition a + charge _ = Nothing instance Formula EmpiricalFormula where renderFormula f = foldMap renderFoldfunc diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isotope-0.4.0.0/src/Isotope/Ion.hs new/isotope-0.5.0.1/src/Isotope/Ion.hs --- old/isotope-0.4.0.0/src/Isotope/Ion.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/isotope-0.5.0.1/src/Isotope/Ion.hs 2017-04-29 12:29:38.000000000 +0200 @@ -0,0 +1,70 @@ +{-| +Module : Isotope.Ion +Description : Provides support for ions. +Copyright : Michael Thomas +License : GPL-3 +Maintainer : Michael Thomas <michaelt...@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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isotope-0.4.0.0/test/Isotope/BaseSpec.hs new/isotope-0.5.0.1/test/Isotope/BaseSpec.hs --- old/isotope-0.4.0.0/test/Isotope/BaseSpec.hs 2017-03-11 09:41:07.000000000 +0100 +++ new/isotope-0.5.0.1/test/Isotope/BaseSpec.hs 2017-04-29 12:29:38.000000000 +0200 @@ -115,6 +115,8 @@ describe "ToElementalComposition - ElementalComposition instance" $ do it "toElementalComposition" . property $ \ec -> toElementalComposition ec == (ec :: ElementalComposition) + it "charge of an elemental composition should Just 0" . property $ + \ec -> charge (ec :: ElementalComposition) == Nothing it "monoisotopic mass of ethanol" $ withinTolerance (getMonoisotopicMass (monoisotopicMass [ele|C2H6O|])) 46.04186 0.0001 `shouldBe` True @@ -130,9 +132,11 @@ it "should give the correct formula" $ mkElementalComposition [(C, 2), (H, 6), (O, 1)] `shouldBe` [ele|C2H6O|] - describe "ToElementalComposition - ElementSymbol instance" . + describe "ToElementalComposition - ElementSymbol instance" $ do it "monoisotopicMass" . property $ \sym -> monoisotopicMass sym == monoisotopicMass (mkElementalComposition [(sym, 1)]) + it "charge of a symbol should be Just 0" . property $ + \sym -> charge (sym :: ElementSymbol) == Nothing describe "Monoid instance for MolecularFormula" $ do it "associativity" . property $ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isotope-0.4.0.0/test/Isotope/IonSpec.hs new/isotope-0.5.0.1/test/Isotope/IonSpec.hs --- old/isotope-0.4.0.0/test/Isotope/IonSpec.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/isotope-0.5.0.1/test/Isotope/IonSpec.hs 2017-04-29 12:29:38.000000000 +0200 @@ -0,0 +1,22 @@ +module Isotope.IonSpec (spec) where + +import Isotope +import Isotope.Ion +import Test.Hspec + +spec :: Spec +spec = do + describe "mz" $ do + it "The mass-to-charge ratio of protonated water should be 19.01838971626" $ + mz (Protonated water) `shouldBe` Mz {getMz = 19.01838971626} + it "The mass-to-charge ratio of deprotonated water should be 17.0027396518" $ + mz (Deprotonated water) `shouldBe` Mz {getMz = 17.0027396518} + + describe "polarity" $ do + it "The polarity of protonated water should be Positive" $ + polarity (Protonated water) `shouldBe` Positive + it "The polarity of deprotonated water should be Negative" $ + polarity (Deprotonated water) `shouldBe` Negative + +water :: MolecularFormula +water = mkMolecularFormula [(H, 2), (O, 1)] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isotope-0.4.0.0/test/Spec.hs new/isotope-0.5.0.1/test/Spec.hs --- old/isotope-0.4.0.0/test/Spec.hs 2016-11-12 04:43:36.000000000 +0100 +++ new/isotope-0.5.0.1/test/Spec.hs 2017-04-29 12:29:38.000000000 +0200 @@ -4,8 +4,10 @@ import Test.QuickCheck import Isotope.BaseSpec import Isotope.ParsersSpec +import Isotope.IonSpec main :: IO () main = hspec $ do describe "Base" Isotope.BaseSpec.spec describe "Parsers" Isotope.ParsersSpec.spec + describe "Ion" Isotope.IonSpec.spec