module Chemistry.Element ( Element
, atomicNumber
, element
, elementByAtomNumber
, shellElectrons
, valenceElectronCount
, valenceBoundCount
) where
data Element = Element { atomicNumber :: Int
, symbol :: String
, _name :: String
, _weight :: Double }
deriving Show
elements :: [Element]
elements = [ Element 1 "H" "Hydrogen" 1.008
, Element 2 "He" "Helium" 4.002602
, Element 3 "Li" "Lithium" 6.941
, Element 4 "Be" "Beryllium" 9.012182
, Element 5 "B" "Boron" 10.811
, Element 6 "C" "Carbon" 12.011
, Element 7 "N" "Nitrogen" 14.007
, Element 8 "O" "Oxygen" 15.999
, Element 9 "F" "Fluorine" 18.9984032
, Element 10 "Ne" "Neon" 20.1797
, Element 11 "Na" "Sodium" 22.989768
, Element 12 "Mg" "Magnesium" 24.305
, Element 13 "Al" "Alluminium" 26.981
, Element 14 "Si" "Silicon" 28.085
, Element 15 "P" "Phosphous" 30.973
, Element 16 "S" "Sulphur" 32.066
, Element 17 "Cl" "Chlorine" 35.4527
, Element 18 "Ar" "Argon" 39.948
, Element 19 "K" "Potassium" 39.0983
, Element 20 "Ca" "Calcium" 40.078
, Element 21 "Sc" "Scandium" 44.95591
, Element 22 "Ti" "Titanium" 47.88
, Element 23 "V" "Vanadium" 50.9415
, Element 24 "Cr" "Chromium" 51.9961
, Element 25 "Mn" "Manganese" 54.93805
, Element 26 "Fe" "Iron" 55.845
, Element 27 "Co" "Cobalt" 58.933
, Element 28 "Ni" "Nickel" 58.6934
, Element 29 "Cu" "Copper" 63.546
, Element 43 "Tc" "Technetium" 98.9063
, Element 55 "Cs" "Caesium" 132.90543
, Element 56 "Ba" "Barium" 137.327
, Element 57 "La" "Lanthanum" 138.9055
, Element 58 "Ce" "Cerium" 140.115
, Element 59 "Pr" "Praseodymium" 140.90765
, Element 60 "Nd" "Neodymium" 144.24
, Element 61 "Pm" "Promethium" 146.9151
, Element 73 "Ta" "Tantalum" 180.9479
, Element 80 "Hg" "Mercury" 200.59
, Element 86 "Rn" "Radon" 222.0176
, Element 90 "Th" "Thorium" 232.0381
, Element 97 "Bk" "Berkelium" 247.0703
, Element 104 "Rf" "Rutherfordium" 261.1087
, Element 112 "Cn" "Copernicium" 285
, Element 113 "Uut" "Ununtrium" 284
, Element 114 "Uug" "Ununquadium" 289
, Element 115 "Uup" "Ununpentium" 288
, Element 116 "Uuh" "Ununhexium" 293
, Element 117 "Uus" "Ununseptium" 294
, Element 118 "Uuo" "Ununoctium" 294 ]
elementByAtomNumber :: Int -> Maybe Element
elementByAtomNumber n = f n elements
where f :: Int -> [Element] -> Maybe Element
f _ [] = Nothing
f x (e:es) | (atomicNumber e) == x = Just e
| otherwise = f x es
element :: String -> Maybe Element
element ns = f ns elements
where f :: String -> [Element] -> Maybe Element
f _ [] = Nothing
f xs (e:es) | (symbol e) == xs = Just e
| otherwise = f xs es
shellElectrons :: Element -> [Int]
shellElectrons e = filter (> 0) $ f (fillShells (atomicNumber e))
where f :: [(Int, Int, Int)] -> [Int]
f ss = [sum (g n ss) | n <- [1..m]]
where m = ((length ss) + 1) `div` 2
g l = map (\(a,_,c) -> if a == l then c else 0)
valenceElectronCount :: Element -> Int
valenceElectronCount e = head $ reverse (shellElectrons e)
valenceBoundCount :: Element -> Int
valenceBoundCount e = min n (8n)
where n = valenceElectronCount e
subshellMaxElectrons :: [Int]
subshellMaxElectrons = [2, 6, 10, 14, 18]
shellConfigGen :: Int -> [(Int, Int)]
shellConfigGen n = [(i,mi) | m <- [2..n+n], i <- [((m+1) `div` 2)..m1] ]
fillShells :: Int -> [( Int
, Int
, Int
)]
fillShells n = f (shellConfigGen 5) n
where f :: [(Int, Int)] -> Int -> [(Int, Int, Int)]
f [] _ = []
f ((i,j):xs) m | m == 0 = []
| m < l = [(i, j, m)]
| otherwise = (i, j, l) : (f xs (ml))
where l = subshellMaxElectrons !! (j1)