{-# LANGUAGE TypeOperators, TemplateHaskell #-}

-----------------------------------------------------------------------------
-- |
-- Module      :  Data.Units.SI.Prefixes
-- Copyright   :  (C) 2013 Richard Eisenberg
-- License     :  BSD-style (see LICENSE)
-- Maintainer  :  Richard Eisenberg (rae@cs.brynmawr.edu)
-- Stability   :  experimental
-- Portability :  non-portable
--
-- Defines prefixes from the SI standard at <http://www.bipm.org/en/si/>
-----------------------------------------------------------------------------

module Data.Units.SI.Prefixes where

import Language.Haskell.TH ( Name )
import Data.Metrology.Poly

-- | 10^1
data Deca = Deca
instance UnitPrefix Deca where
  multiplier :: Deca -> f
multiplier Deca
_ = f
1e1
instance Show Deca where
  show :: Deca -> String
show Deca
_ = String
"da"

deca :: unit -> Deca :@ unit
deca :: unit -> Deca :@ unit
deca = (Deca
Deca Deca -> unit -> Deca :@ unit
forall prefix unit. prefix -> unit -> prefix :@ unit
:@)

-- | 10^2
data Hecto = Hecto
instance UnitPrefix Hecto where
  multiplier :: Hecto -> f
multiplier Hecto
_ = f
1e2
instance Show Hecto where
  show :: Hecto -> String
show Hecto
_ = String
"h"

hecto :: unit -> Hecto :@ unit
hecto :: unit -> Hecto :@ unit
hecto = (Hecto
Hecto Hecto -> unit -> Hecto :@ unit
forall prefix unit. prefix -> unit -> prefix :@ unit
:@)

-- | 10^3
data Kilo = Kilo
instance UnitPrefix Kilo where
  multiplier :: Kilo -> f
multiplier Kilo
_ = f
1e3
instance Show Kilo where
  show :: Kilo -> String
show Kilo
_ = String
"k"

kilo :: unit -> Kilo :@ unit
kilo :: unit -> Kilo :@ unit
kilo = (Kilo
Kilo Kilo -> unit -> Kilo :@ unit
forall prefix unit. prefix -> unit -> prefix :@ unit
:@)

-- | 10^6
data Mega = Mega
instance UnitPrefix Mega where
  multiplier :: Mega -> f
multiplier Mega
_ = f
1e6
instance Show Mega where
  show :: Mega -> String
show Mega
_ = String
"M"

mega :: unit -> Mega :@ unit
mega :: unit -> Mega :@ unit
mega = (Mega
Mega Mega -> unit -> Mega :@ unit
forall prefix unit. prefix -> unit -> prefix :@ unit
:@)

-- | 10^9
data Giga = Giga
instance UnitPrefix Giga where
  multiplier :: Giga -> f
multiplier Giga
_ = f
1e9
instance Show Giga where
  show :: Giga -> String
show Giga
_ = String
"G"

giga :: unit -> Giga :@ unit
giga :: unit -> Giga :@ unit
giga = (Giga
Giga Giga -> unit -> Giga :@ unit
forall prefix unit. prefix -> unit -> prefix :@ unit
:@)

-- | 10^12
data Tera = Tera
instance UnitPrefix Tera where
  multiplier :: Tera -> f
multiplier Tera
_ = f
1e12
instance Show Tera where
  show :: Tera -> String
show Tera
_ = String
"T"

tera :: unit -> Tera :@ unit
tera :: unit -> Tera :@ unit
tera = (Tera
Tera Tera -> unit -> Tera :@ unit
forall prefix unit. prefix -> unit -> prefix :@ unit
:@)

-- | 10^15
data Peta = Peta
instance UnitPrefix Peta where
  multiplier :: Peta -> f
multiplier Peta
_ = f
1e15
instance Show Peta where
  show :: Peta -> String
show Peta
_ = String
"P"

peta :: unit -> Peta :@ unit
peta :: unit -> Peta :@ unit
peta = (Peta
Peta Peta -> unit -> Peta :@ unit
forall prefix unit. prefix -> unit -> prefix :@ unit
:@)

-- | 10^18
data Exa = Exa
instance UnitPrefix Exa where
  multiplier :: Exa -> f
multiplier Exa
_ = f
1e18
instance Show Exa where
  show :: Exa -> String
show Exa
_ = String
"E"

exa :: unit -> Exa :@ unit
exa :: unit -> Exa :@ unit
exa = (Exa
Exa Exa -> unit -> Exa :@ unit
forall prefix unit. prefix -> unit -> prefix :@ unit
:@)

-- | 10^21
data Zetta = Zetta
instance UnitPrefix Zetta where
  multiplier :: Zetta -> f
multiplier Zetta
_ = f
1e21
instance Show Zetta where
  show :: Zetta -> String
show Zetta
_ = String
"Z"

zetta :: unit -> Zetta :@ unit
zetta :: unit -> Zetta :@ unit
zetta = (Zetta
Zetta Zetta -> unit -> Zetta :@ unit
forall prefix unit. prefix -> unit -> prefix :@ unit
:@)

-- | 10^24
data Yotta = Yotta
instance UnitPrefix Yotta where
  multiplier :: Yotta -> f
multiplier Yotta
_ = f
1e24
instance Show Yotta where
  show :: Yotta -> String
show Yotta
_ = String
"Y"

yotta :: unit -> Yotta :@ unit
yotta :: unit -> Yotta :@ unit
yotta = (Yotta
Yotta Yotta -> unit -> Yotta :@ unit
forall prefix unit. prefix -> unit -> prefix :@ unit
:@)

-- | 10^-1
data Deci = Deci
instance UnitPrefix Deci where
  multiplier :: Deci -> f
multiplier Deci
_ = f
1e-1
instance Show Deci where
  show :: Deci -> String
show Deci
_ = String
"d"

deci :: unit -> Deci :@ unit
deci :: unit -> Deci :@ unit
deci = (Deci
Deci Deci -> unit -> Deci :@ unit
forall prefix unit. prefix -> unit -> prefix :@ unit
:@)

-- | 10^-2
data Centi = Centi
instance UnitPrefix Centi where
  multiplier :: Centi -> f
multiplier Centi
_ = f
1e-2
instance Show Centi where
  show :: Centi -> String
show Centi
_ = String
"c"

centi :: unit -> Centi :@ unit
centi :: unit -> Centi :@ unit
centi = (Centi
Centi Centi -> unit -> Centi :@ unit
forall prefix unit. prefix -> unit -> prefix :@ unit
:@)

-- | 10^-3
data Milli = Milli
instance UnitPrefix Milli where
  multiplier :: Milli -> f
multiplier Milli
_ = f
1e-3
instance Show Milli where
  show :: Milli -> String
show Milli
_ = String
"m"

milli :: unit -> Milli :@ unit
milli :: unit -> Milli :@ unit
milli = (Milli
Milli Milli -> unit -> Milli :@ unit
forall prefix unit. prefix -> unit -> prefix :@ unit
:@)

-- | 10^-6
data Micro = Micro
instance UnitPrefix Micro where
  multiplier :: Micro -> f
multiplier Micro
_ = f
1e-6
instance Show Micro where
  show :: Micro -> String
show Micro
_ = String
"μ"

micro :: unit -> Micro :@ unit
micro :: unit -> Micro :@ unit
micro = (Micro
Micro Micro -> unit -> Micro :@ unit
forall prefix unit. prefix -> unit -> prefix :@ unit
:@)

-- | 10^-9
data Nano = Nano
instance UnitPrefix Nano where
  multiplier :: Nano -> f
multiplier Nano
_ = f
1e-9
instance Show Nano where
  show :: Nano -> String
show Nano
_ = String
"n"

nano :: unit -> Nano :@ unit
nano :: unit -> Nano :@ unit
nano = (Nano
Nano Nano -> unit -> Nano :@ unit
forall prefix unit. prefix -> unit -> prefix :@ unit
:@)

-- | 10^-12
data Pico = Pico
instance UnitPrefix Pico where
  multiplier :: Pico -> f
multiplier Pico
_ = f
1e-12
instance Show Pico where
  show :: Pico -> String
show Pico
_ = String
"p"

pico :: unit -> Pico :@ unit
pico :: unit -> Pico :@ unit
pico = (Pico
Pico Pico -> unit -> Pico :@ unit
forall prefix unit. prefix -> unit -> prefix :@ unit
:@)

-- | 10^-15
data Femto = Femto
instance UnitPrefix Femto where
  multiplier :: Femto -> f
multiplier Femto
_ = f
1e-15
instance Show Femto where
  show :: Femto -> String
show Femto
_ = String
"f"

femto :: unit -> Femto :@ unit
femto :: unit -> Femto :@ unit
femto = (Femto
Femto Femto -> unit -> Femto :@ unit
forall prefix unit. prefix -> unit -> prefix :@ unit
:@)

-- | 10^-18
data Atto = Atto
instance UnitPrefix Atto where
  multiplier :: Atto -> f
multiplier Atto
_ = f
1e-18
instance Show Atto where
  show :: Atto -> String
show Atto
_ = String
"a"

atto :: unit -> Atto :@ unit
atto :: unit -> Atto :@ unit
atto = (Atto
Atto Atto -> unit -> Atto :@ unit
forall prefix unit. prefix -> unit -> prefix :@ unit
:@)

-- | 10^-21
data Zepto = Zepto
instance UnitPrefix Zepto where
  multiplier :: Zepto -> f
multiplier Zepto
_ = f
1e-21
instance Show Zepto where
  show :: Zepto -> String
show Zepto
_ = String
"z"

zepto :: unit -> Zepto :@ unit
zepto :: unit -> Zepto :@ unit
zepto = (Zepto
Zepto Zepto -> unit -> Zepto :@ unit
forall prefix unit. prefix -> unit -> prefix :@ unit
:@)

-- | 10^-24
data Yocto = Yocto
instance UnitPrefix Yocto where
  multiplier :: Yocto -> f
multiplier Yocto
_ = f
1e-24
instance Show Yocto where
  show :: Yocto -> String
show Yocto
_ = String
"y"

yocto :: unit -> Yocto :@ unit
yocto :: unit -> Yocto :@ unit
yocto = (Yocto
Yocto Yocto -> unit -> Yocto :@ unit
forall prefix unit. prefix -> unit -> prefix :@ unit
:@)

-- | A list of the names of all prefix types. Useful with
-- 'Data.Metrology.Parser.makeQuasiQuoter'.
siPrefixes :: [Name]
siPrefixes :: [Name]
siPrefixes =
  [ ''Deca, ''Hecto, ''Kilo, ''Mega, ''Giga, ''Tera, ''Peta, ''Exa
  , ''Zetta, ''Yotta, ''Deci, ''Centi, ''Milli, ''Micro, ''Nano
  , ''Pico, ''Femto, ''Atto, ''Zepto, ''Yocto
  ]