{- | Module : Chemistry.Formula Copyright : Copyright (C) 2014 Krzysztof Langner License : BSD3 Maintainer : Krzysztof Langner Stability : alpha Portability : portable Formula parser. . Formula can be entered as H2O, SO4+2 (Sulfate) or (CH3)2CO (Acetone) -} module Chemistry.Formula ( Formula(..) , parseFormula ) where import Text.ParserCombinators.Parsec type ElementSymbol = String data Formula = FGroup [(Formula, Int)] | FElement ElementSymbol deriving (Eq, Show) -- | Parse formula -- -- > parseFormula "C2H4" `shouldBe` Formula [(element 6, 2), (element 1, 4)] parseFormula :: String -> Formula parseFormula xs = case parse formula "" xs of Left _ -> FGroup [] Right val -> FGroup val -- Parse whole formula formula :: Parser [(Formula, Int)] formula = many elementSymbol -- Parse element -- Element is max 3 letter long -- Starts with upper case -- has 0, 1 or 2 lower letters elementSymbol :: Parser (Formula, Int) elementSymbol = do l1 <- upper l2 <- many lower let e = FElement (l1:l2) ds <- many digit let n = if null ds then 1 else read ds :: Int return (e, n)