Isotope
Haskell library containing isotopic masses and relative abundances for elements from Hydrogen to Bismuth and Thorium and Uranium (excluding Technetium and promethium), i.e., all elements with naturally-occurring isotopes.
Install / Use
/learn @Michaelt293/IsotopeREADME

- Design
- Isotopic, integer, monoisotopic, nominal and average masses
- Element symbols
- Elemental composition and molecular, condensed and empirical formulae
- ElementalComposition, MolecularFormula, CondensedFormula, EmpiricalFormula quasiquoters
- Conversion between ElementalComposition, MolecularFormula, CondensedFormula and EmpiricalFormula data types
- Operators for working with formulae and masses
- ToElementalComposition type class
- Behaviour of ElementalComposition, MolecularFormula, CondensedFormula and EmpiricalFormula data types
- Additional functions accepting an ElementSymbol as input
- Representing ions in Isotope
- Comparison to other chemistry libraries
- Future directions
- Contributions
- Author
- License
- References
Isotope is a chemistry library for calculating masses of elements and molecules. The main focus of the Isotope library is mass spectrometry, an area where the masses and relative abundances of isotopes and isotopologues is of central importance.
Design
The Isotope library designed with type safety and flexibility in mind. Key features will be described below.
Isotopic, integer, monoisotopic, nominal and average masses
In mass spectrometry and general chemistry, there are several different ways in which to describe mass. This can lead to some confusion since more than one term can exist to describe the same unit of measurement. In the Isotope library, the following conventions are used:
Mass | Description --- | --- Isotopic mass | The mass of an isotope for an element. Integer mass | The mass of an isotope rounded to the nearest integer value. Monoisotopic mass | The mass of the most abundant isotope for an element or the sum of the masses of the most abundant isotope of each element for a molecule. Nominal mass | The integer mass of the most abundant isotope for an element or the sum of integer masses of the most abundant isotope of each element for a molecule. Average mass | The average mass of an element or molecule based on naturally-occurring isotopic abundances. In the Isotope library, average mass is used in place of atomic mass and molecular mass.
For more detailed discussion regarding the concept of mass in mass spectrometry, please refer to "Molecular Weight and the Nominal Mass, Monoisotopic Mass and Average Molar Mass" by Prof. O. David Sparkman [1].
Element symbols
In Isotope, element symbols are represented by the enumeration type, ElementSymbol, i.e. data ElementSymbol = H | He | Li | Be ...... This is advantageous over the use of strings to represent element symbols (i.e. type ElementSymbol = String) since it increases type safety. Moreover, values of type ElementSymbol can be used as keys within maps as an intuitive way to map elements to their properties. Isotope presently contains information on the isotopic masses and relative abundances for all elements from Hydrogen to Bismuth and Thorium and Uranium (excluding Technetium and promethium).
Elemental composition and molecular, condensed and empirical formulae
In the Isotope library, a distinction between elemental composition and molecular, condensed and empirical formulae is made. Molecular formulae contain the total number of atoms for each element of a molecule while condensed formulae give information on the connectivity of atoms within molecules. For example, the molecule trimethylamine has a molecular formula of C3H9N and a condensed formula of N(CH3)3. Here the molecular formula indicates trimethyelamine has a total of 3 carbon atoms, 9 hydrogen atoms and 1 nitrogen whereas the condensed formula indicates trimethylamine has 3 methyl groups bonded to a central nitrogen. Conversely, an empirical formula is the simplest integer ratio for the atoms of a compound. For example, the molecular formula of benzene is C6H6 whereas the empirical formula of benzene is simply CH. Molecular, condensed and empirical formulae may all be considered to have an elemental composition. That is, the total number of atoms for each element for a formulae.
In Isotope, CondensedFormula is defined as a recursive data type. This allows deep nesting within CondensedFormula. For example, triisopropylamine may be expressed as [con|N(CH(CH3)2)3|]. This nesting can therefore be used to convey greater structural detail.
ElementalComposition, MolecularFormula, CondensedFormula, EmpiricalFormula quasiquoters
The quasiquoters, ele, mol, con and emp are provided for ElementalComposition, MolecularFormula, CondensedFormula, EmpiricalFormula and data types, respectively. This allows the use of shorthand notation when working with elemental compositions as well as molecular, condensed and empirical formulae. The use of quasiquoters requires the use of the QuasiQuotes language extension (:set -XQuasiQuotes can be added to the .ghci file when working in GHCi).
GHCi> [mol|CH4|]
MolecularFormula {getMolecularFormula = fromList [(H,4),(C,1)]}
Importantly, errors in formulae will be detected at compile-time and give informative error messages! (Note the example below is from a GHCi session.)
GHCi> [mol|Ch4|]
<interactive>:4:6:
Could not parse formula: 1:2:
unexpected 'h'
expecting "Ag", "Al", "Ar", "As", "Au", "Ba", "Be", "Bi", "Br", "Ca", "Cd", "Ce", "Cl", "Co", "Cr", "Cs", "Cu", "Dy", "Er", "Eu", "Fe", "Ga", "Gd", "Ge", "He", "Hf", "Hg", "Ho", "In", "Ir", "Kr", "La", "Li", "Lu", "Mg", "Mn", "Mo", "Na", "Nb", "Nd", "Ne", "Ni", "Os", "Pa", "Pb", "Pd", "Pm", "Pr", "Pt", "Rb", "Re", "Rh", "Ru", "Sb", "Sc", "Se", "Si", "Sm", "Sn", "Sr", "Ta", "Tb", "Tc", "Te", "Th", "Ti", "Tl", "Tm", "Xe", "Yb", "Zn", "Zr", '(', 'B', 'C', 'F', 'H', 'I', 'K', 'N', 'O', 'P', 'S', 'U', 'V', 'W', 'Y', or end of input
Conversion between ElementalComposition, MolecularFormula, CondensedFormula and EmpiricalFormula data types
A condensed formula can be converted to a molecular or empirical formula and a molecular formula can be converted to an empirical formula. All formulae can be converted to an ElementalComposition and an ElementalComposition may be converted to an EmpiricalFormula In Isotope, this functionality is provided by three type classes, ToElementalComposition, ToMolecularFormula and ToEmpiricalFormula, which contain the methods, ToElementalComposition, toMolecularFormula and toEmpiricalFormula, respectively. In addition, a ToCondensedFormula type class containing the toCondensedFormula method is also provided for users of Isotope.
GHCi> let butane = [con|CH3(CH2)2CH3|]
GHCi> toElementalComposition butane
ElementalComposition {getElementalComposition = fromList [(H,10),(C,4)]}
GHCi> toMolecularFormula butane
MolecularFormula {getMolecularFormula = fromList [(H,10),(C,4)]}
GHCi> toEmpiricalFormula butane
EmpiricalFormula {getEmpiricalFormula = fromList [(H,5),(C,2)]}
When using quasiquoters, it is possible to do this implicitly. For example, the quasiquoter emp could be applied to the condensed formula CH3(CH2)2CH3 used above to yield a value of type EmpiricalFormula.
GHCi> [emp|CH3(CH2)2CH3|]
EmpiricalFormula {getEmpiricalFormula = fromList [(H,5),(C,2)]}
Operators for working with formulae and masses
The Isotope library comes with three operators for working with formulae and masses; |+|, |-| and |*|. These operators are provided in the Operators type class and have the same fixity and associativity as +, - and *, respectively. This allows us to the |+|, |-| and |*| operators in an intuitive manner (i.e., like basic arithmetic). For example, we could define the molecule formula of propane in terms of its building blocks; that is, 2 methyl groups and 1 methylene group.
GHCi> let methyl = [mol|CH3|]
GHCi> let methylene = [mol|CH2|]
GHCi> let propane = methyl |*| 2 |+| methylene
GHCi> propane
MolecularFormula {getMolecularFormula = fromList [(H,8),(C,3)]}
We could then go one step further and define propene to be propane minus molecular hydrogen.
GHCi> let propene = propane |-| [mol|H2|]
GHCi> propene
MolecularFormula {getMolecularFormula = fromList [(H,6),(C,3)]}
ToElementalComposition type class
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 compos
Related Skills
next
A beautifully designed, floating Pomodoro timer that respects your workspace.
product-manager-skills
31PM skill for Claude Code, Codex, Cursor, and Windsurf: diagnose SaaS metrics, critique PRDs, plan roadmaps, run discovery, and coach PM career transitions.
devplan-mcp-server
3MCP server for generating development plans, project roadmaps, and task breakdowns for Claude Code. Turn project ideas into paint-by-numbers implementation plans.
