-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | A parser for units of measure
--   
--   The <tt>units-parser</tt> package provides a parser for unit
--   expressions with F#-style syntax, to support the <tt>units</tt>
--   package and other packages providing type-level units of measure.
@package units-parser
@version 0.1.0.0


-- | This module defines a parser for unit expressions. The syntax for
--   these expressions is like F#'s. There are four arithmetic operators
--   (<tt>*</tt>, <tt>/</tt>, <tt>^</tt>, and juxtaposition).
--   Exponentiation binds the tightest, and it allows an integer to its
--   right (possibly with minus signs and parentheses). Next tightest is
--   juxtaposition, which indicates multiplication. Because juxtaposition
--   binds tighter than division, the expressions <tt>m/s^2</tt> and
--   <tt>m/s s</tt> are equivalent. Multiplication and division bind the
--   loosest and are left-associative, meaning that <tt>m/s*s</tt> is
--   equivalent to <tt>(m/s)*s</tt>, probably not what you meant.
--   Parentheses in unit expressions are allowed, of course.
--   
--   Within a unit string (that is, a unit with an optional prefix), there
--   may be ambiguity. If a unit string can be interpreted as a unit
--   without a prefix, that parsing is preferred. Thus, <tt>min</tt> would
--   be minutes, not milli-inches (assuming appropriate prefixes and units
--   available.) There still may be ambiguity between unit strings, even
--   interpreting the string as a prefix and a base unit. If a unit string
--   is amiguous in this way, it is rejected. For example, if we have
--   prefixes <tt>da</tt> and <tt>d</tt> and units <tt>m</tt> and
--   <tt>am</tt>, then <tt>dam</tt> is ambiguous like this.
module Text.Parse.Units

-- | Parsed unit expressions, parameterized by a prefix identifier type and
--   a unit identifier type
data UnitExp pre u

-- | "1"
Unity :: UnitExp pre u

-- | a unit with, perhaps, a prefix
Unit :: (Maybe pre) -> u -> UnitExp pre u
Mult :: (UnitExp pre u) -> (UnitExp pre u) -> UnitExp pre u
Div :: (UnitExp pre u) -> (UnitExp pre u) -> UnitExp pre u
Pow :: (UnitExp pre u) -> Integer -> UnitExp pre u

-- | Parse a unit expression, interpreted with respect the given symbol
--   table. Returns either an error message or the successfully-parsed unit
--   expression.
parseUnit :: (Show pre, Show u) => SymbolTable pre u -> String -> Either String (UnitExp pre u)

-- | A "symbol table" for the parser, mapping prefixes and units to their
--   representations.
data SymbolTable pre u
SymbolTable :: PrefixTable pre -> UnitTable u -> SymbolTable pre u
[prefixTable] :: SymbolTable pre u -> PrefixTable pre
[unitTable] :: SymbolTable pre u -> UnitTable u

-- | A finite mapping from prefix spellings to prefix identifiers (of
--   unspecified type <tt>pre</tt>). All prefix spellings must be strictly
--   alphabetic.
type PrefixTable pre = Map String pre

-- | A mapping from unit spellings to unit identifiers (of unspecified type
--   <tt>u</tt>). All unit spellings must be strictly alphabetic.
type UnitTable u = String -> Maybe u

-- | Build a symbol table from prefix mappings and unit mappings. The
--   prefix mapping can be empty. This function checks to make sure that
--   the strings are not inherently ambiguous and are purely alphabetic.
mkSymbolTable :: (Show pre, Show u) => [(String, pre)] -> [(String, u)] -> Either String (SymbolTable pre u)

-- | Make a symbol table without checking for ambiguity or non-purely
--   alphabetic strings. The prefixes must be a (potentially empty) finite
--   map, but the units mapping need not be finite. Note that this is
--   unsafe in that the resulting parser may behave unpredictably. It
--   surely won't launch the rockets, though.
unsafeMkSymbolTable :: PrefixTable pre -> UnitTable u -> SymbolTable pre u

-- | A symbol table that accepts all unit strings, but supports no
--   prefixes.
universalSymbolTable :: SymbolTable a String
lex :: String -> Either ParseError [Token]
unitStringParser :: UnitStringParser_UnitExp
instance GHC.Show.Show Text.Parse.Units.Op
instance GHC.Show.Show Text.Parse.Units.Token
instance (GHC.Show.Show pre, GHC.Show.Show u) => GHC.Show.Show (Text.Parse.Units.UnitExp pre u)
