diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,5 @@
+# Revision history for gev-test
+
+## 0.1.0.0 -- YYYY-mm-dd
+
+* First version. Released on an unsuspecting world.
diff --git a/gev-lib.cabal b/gev-lib.cabal
new file mode 100644
--- /dev/null
+++ b/gev-lib.cabal
@@ -0,0 +1,45 @@
+cabal-version:      2.4
+name:               gev-lib
+version:            0.1.0.0
+
+-- A short (one-line) description of the package.
+synopsis: The family of Extreme Value Distributions.
+
+-- A longer description of the package.
+description: Basic Distributional quantities (CDF, PDF, Quantile) for the Gumbel, Féchet, Weibull and GEV Distributions.
+
+-- A URL where users can report bugs.
+-- bug-reports:
+
+-- The license under which the package is released.
+license: ISC
+
+-- The package author(s).
+author: Gabriel Haeck
+
+-- An email address to which users can send suggestions, bug reports, and patches.
+maintainer: haeckgabriel@gmail.com
+
+-- A copyright notice.
+-- copyright:
+category: Statistics
+extra-source-files: CHANGELOG.md
+
+library gev-dist
+    exposed-modules:  Gev, Gev.Gumbel, Gev.Frechet, Gev.Weibull, Gev.GevDist
+
+    -- Modules included in this library but not exported.
+    -- other-modules:
+
+    -- LANGUAGE extensions used by modules in this package.
+    -- other-extensions:
+    build-depends:    base ^>=4.14.3.0, random
+    hs-source-dirs:   src
+    default-language: Haskell2010
+
+test-suite tests
+  type: exitcode-stdio-1.0
+  hs-source-dirs: .
+  main-is: src/Tests/tests.hs
+  build-depends: base ^>=4.14.3.0, HUnit ^>=1.6, gev-dist
+  default-language: Haskell2010
diff --git a/src/Gev.hs b/src/Gev.hs
new file mode 100644
--- /dev/null
+++ b/src/Gev.hs
@@ -0,0 +1,50 @@
+module Gev ( Distribution(..) ) where
+
+import System.Random.Stateful (StatefulGen, uniformDouble01M)
+
+-- | Distribution Class for the GEV family of distributions. That is, each of the 
+-- distributions considered will have a CDF, PDF and Quantile function.
+class Distribution d where
+    -- | Cumulative Distribution Function (CDF) of a given distribution.
+    -- i.e. $\mathbb{P}(X \leq x)$ for $x \in \Omega(X)$ (i.e. x is in the support of X)
+    --
+    -- > cdf d +∞ = 1
+    -- > cdf d -∞ = 0
+    cdf :: d -> Double -> Double
+    cdf d x = 1 - complCdf d x
+
+    -- | Complement of the CDF, i.e. $\mathbb{P}(X \geq x)$.
+    complCdf :: d -> Double -> Double
+    complCdf d x = 1 - cdf d x
+
+    -- | Probability Density Function (pdf) of a distribution.
+    -- i.e. $\mathbb{P}(X = x)$  for $x \in \Omega(X)$ (i.e. x is in the support of X)
+    pdf :: d -> Double -> Double
+    pdf d = exp . logPdf d
+    
+    -- | Log density of a given distribution
+    -- i.e. density for $Y = \log X$
+    logPdf :: d -> Double -> Double
+    logPdf d = log . pdf d
+
+    -- | Quantile function (a.k.a inverse CDF) of a distribution.
+    -- i.e. $F^{-1}(x)$ for $x \in [0, 1]$.
+    quantile :: d -> Double -> Double
+    quantile d x = complQuantile d (1- x)
+
+    -- | Quantile complement, i.e. Quantile for level $1 - \alpha$.
+    complQuantile :: d -> Double -> Double
+    complQuantile d x = quantile d (1 - x)
+
+    -- | generate random value of the Distribution.
+    randGen :: StatefulGen g m => d -> g -> m Double
+    randGen d gen = do
+        x <- uniformDouble01M gen
+        return $! quantile d x
+    {-# MINIMAL (cdf | complCdf), (pdf | logPdf), (quantile | complQuantile) #-}
+
+-- see https://hackage.haskell.org/package/statistics-0.16.1.2/docs/src/Statistics.Distribution.html#genContinuous
+--genContinuous :: (ContDistr d, StatefulGen g m) => d -> g -> m Double
+--genContinuous d gen = do
+--  x <- uniformDouble01M gen
+--  return $! quantile d x
diff --git a/src/Gev/Frechet.hs b/src/Gev/Frechet.hs
new file mode 100644
--- /dev/null
+++ b/src/Gev/Frechet.hs
@@ -0,0 +1,77 @@
+module Gev.Frechet
+    (
+      FrechetDistribution
+     -- * constructors
+    , frechetDist
+    , frechetDistMaybe
+     -- * accessors
+    , location
+    , scale
+    , shape
+    ) where
+
+import qualified Gev
+
+data FrechetDistribution = Frechet {
+      location :: {-# UNPACK #-} !Double
+    , scale    :: {-# UNPACK #-} !Double
+    , shape    :: {-# UNPACK #-} !Double
+    } deriving (Eq)
+
+instance Show FrechetDistribution where
+    show (Frechet loc sc sh) = show "Frechet Distribution; loc: " ++ show loc ++ ", scale: " ++ show sc ++ " and shape: " ++ show sh
+
+-- error message when initiating Frechet with scale parameter less than 0.
+frechetErrMsg :: Double -> Double -> Double -> String
+frechetErrMsg loc scale sh = "Gev.Frechet: " 
+    ++ "loc = " ++ show loc
+    ++ " scale = " ++ show scale
+    ++ " schape = " ++ show sh
+    ++ ", but both the scale and shape parameters must be positive!"
+
+-- | create Frechet Dist, where scale parameter must be greater than 0.
+frechetDistMaybe :: Double -> Double -> Double -> Maybe FrechetDistribution
+frechetDistMaybe loc sc sh
+    | sc > 0 && sh > 0    = Just $ Frechet loc sc sh
+    | otherwise = Nothing
+
+-- | create Frechet Dist, where scale parameter must be greater than 0.
+frechetDist :: Double -> Double -> Double -> FrechetDistribution
+frechetDist loc sc sh = maybe (error $ frechetErrMsg loc sc sh) id $ frechetDistMaybe loc sc sh
+
+-- | The CDF of the Frechet distribution
+cdfFrechet :: FrechetDistribution -> Double -> Double
+cdfFrechet (Frechet loc sc sh) x
+    | x <= 0     = 0
+    | otherwise  = exp $ - (y ** pow)
+        where 
+            y   = (x - loc) / sc
+            pow = - sh
+
+-- | The PDF of the Frechet distribution
+pdfFrechet :: FrechetDistribution -> Double -> Double
+pdfFrechet (Frechet loc sc sh) x =
+    let y       = (x - loc) / sc
+        const   = sh / sc
+        expterm = exp $ - (y ** (- sh))
+        middle  = y ** (-1 - sh)
+    in const * middle * expterm
+
+-- Quantile function of the Frechet Distribution
+quantileFrechet :: FrechetDistribution -> Double -> Double
+quantileFrechet (Frechet loc sc sh) x
+    | x == 0         = -inf
+    | x == 1         = inf
+    | x > 0 && x < 1 = loc + sc * (logexp ** pow)
+    | otherwise      =
+        error $ "Gev.FrechetDistribution.quantile: The given value must be between 0 and 1, got: " ++ show x
+    where 
+        inf    = 1 / 0
+        logexp = - log x
+        pow    = - 1 / sh
+
+-- | Gev.Distribution instance implementation for the Frechet Distribution
+instance Gev.Distribution FrechetDistribution where
+    cdf      = cdfFrechet
+    pdf      = pdfFrechet
+    quantile = quantileFrechet
diff --git a/src/Gev/GevDist.hs b/src/Gev/GevDist.hs
new file mode 100644
--- /dev/null
+++ b/src/Gev/GevDist.hs
@@ -0,0 +1,98 @@
+module Gev.GevDist 
+    (
+     GevDistribution
+     -- * constructors
+    , gevDist
+    , gevDistMaybe
+     -- * accessors
+    , location
+    , scale
+    , shape
+    ) where
+
+import qualified Gev
+
+data GevDistribution = GEV {
+      location :: {-# UNPACK #-} !Double
+    , scale    :: {-# UNPACK #-} !Double
+    , shape    :: {-# UNPACK #-} !Double
+    } deriving (Eq)
+
+instance Show GevDistribution where
+    show (GEV loc sc sh) = show "GEV Distribution; loc: " ++ show loc ++ ", scale: " ++ show sc ++ " and shape: " ++ show sh
+
+-- error message when initiating GEV Distribution with scale parameter less than 0.
+gevErrMsg :: Double -> Double -> Double -> String
+gevErrMsg loc scale sh = "Gev.GevDist: " 
+    ++ "loc = " ++ show loc
+    ++ " scale = " ++ show scale
+    ++ " schape = " ++ show sh
+    ++ ", but the scale parameter must be positive!"
+
+gevDistMaybe :: Double -> Double -> Double -> Maybe GevDistribution
+gevDistMaybe loc sc sh
+    | sc > 0 = Just $ GEV loc sc sh
+    | otherwise = Nothing
+
+gevDist :: Double -> Double -> Double -> GevDistribution
+gevDist loc sc sh = maybe (error $ gevErrMsg loc sc sh) id $ gevDistMaybe loc sh sc
+
+-- | helper function: checks that the given x value falls in the valid part of the GEV domain.
+-- -- actually this i isn't needed, just included as a guard pattern it'll be fine..
+gevDomainCheck :: GevDistribution -> Double -> Bool
+gevDomainCheck (GEV loc sc sh) x =
+    if 1 + sh * (x - loc / sc) > 0 then True else False
+
+-- | t(x) function depends on if the shape parameter (\zeta) is 0 or not.
+-- t(x) = \exp \left(x) = \left( 1 + \zeta \left( \frac{x - \mu}{ \sigma} \right) \right)^{- \frac{1}{\zeta}}$$ if $\zeta \neq 0$,
+--  or $t(x) = \exp \left \{ - \frac{x - \mu}{ \sigma }  \right \}$ if $\zeta = 0$
+gevArg :: Double -> Double -> Double -> Double -> Double
+gevArg loc sc sh x =
+    if sh == 0 then one else two
+        where
+            y   = (x - loc) / sc
+            one = exp $ - y
+            two = (1 + sh * y) ** (- 1 / sh)
+   
+-- | CDF of the GEV Distribution.
+cdfGEV :: GevDistribution -> Double -> Double
+cdfGEV (GEV loc sc sh) x
+   | x <= 0                       = 0
+   | 1 + sh * (x - loc / sc) > 0  = exp $ - tVal
+   | otherwise =
+        error $ "Gev.GevDist.cdf: The given x value is not in the support of the Distribution: " ++ show x
+   where
+       tVal = gevArg loc sc sh x
+        
+
+-- | PDF of the GEV Distribution.
+pdfGEV :: GevDistribution -> Double -> Double
+pdfGEV (GEV loc sc sh) x
+   | 1 + sh * (x - loc / sc) > 0  = const * middle * exp ( - tVal)
+   | otherwise =
+        error $ "Gev.GevDist.pdf: The given x value is not in the support of the Distribution: " ++ show x
+   where
+       tVal   = gevArg loc sc sh x
+       const  = 1 / sc
+       middle = tVal ** (sh + 1)
+
+-- | Quantile function of the GEV Distribution
+-- Quantile function of the Frechet Distribution
+quantileGEV :: GevDistribution -> Double -> Double
+quantileGEV (GEV loc sc sh) x
+    | x == 0         = -inf
+    | x == 1         = inf
+    | x > 0 && x < 1 = if sh == 0 then one else two
+    | otherwise      =
+        error $ "Gev.GEVDist.quantile: The given value must be between 0 and 1, got: " ++ show x
+    where 
+        inf   = 1 / 0
+        logx  = - log x
+        one   = - sc * log logx + loc
+        const = sc / sh
+        two   = const * (logx ** (- sh)) - const + loc
+
+instance Gev.Distribution GevDistribution where
+    cdf      = cdfGEV
+    pdf      = pdfGEV
+    quantile = quantileGEV
diff --git a/src/Gev/Gumbel.hs b/src/Gev/Gumbel.hs
new file mode 100644
--- /dev/null
+++ b/src/Gev/Gumbel.hs
@@ -0,0 +1,68 @@
+module Gev.Gumbel
+    (
+      GumbelDistribution
+    -- * Constructors
+    , gumbelDist
+    , gumbelDistMaybe
+    -- * Accessors
+    , location
+    , scale
+    ) where
+
+import qualified Gev
+-- import Numeric.SpecFunctions (log1p,expm1) POSSIBLY!!!
+
+data GumbelDistribution = Gumbel {
+      location :: {-# UNPACK #-} !Double
+    , scale    :: {-# UNPACK #-} !Double
+    } deriving (Eq)
+
+instance Show GumbelDistribution where
+    show (Gumbel loc sc) = show "Gumbel Distribution; loc: " ++ show loc ++ " and scale: " ++ show sc
+
+-- error message when initiating Gumbel with scale parameter less than 0.
+gumbelErrMsg :: Double -> Double -> String
+gumbelErrMsg loc scale = "Gev.Gumbel: " 
+    ++ "loc = " ++ show loc
+    ++ " scale = " ++ show scale
+    ++ ", but the scale parameter must be positive!"
+
+-- | create Gumbel Dist, where scale parameter must be greater than 0.
+gumbelDistMaybe :: Double -> Double -> Maybe GumbelDistribution
+gumbelDistMaybe loc sc
+    | sc > 0    = Just $ Gumbel loc sc
+    | otherwise = Nothing
+
+-- | create Gumbel Dist, where scale parameter must be greater than 0.
+gumbelDist :: Double -> Double -> GumbelDistribution
+gumbelDist loc sc = maybe (error $ gumbelErrMsg loc sc) id $ gumbelDistMaybe loc sc
+
+-- | The CDF of the Gumbel distribution
+cdfGumbel :: GumbelDistribution -> Double -> Double
+cdfGumbel (Gumbel loc sc) x
+    | x <= 0     = 0
+    | otherwise  = exp $ - (exp y)
+        where 
+            y = - (x - loc) / sc
+
+-- | The PDf of the Gumbel distribution
+pdfGumbel :: GumbelDistribution -> Double -> Double
+pdfGumbel (Gumbel loc sc) x =
+    let exp_y = exp $ - (x- loc) / sc
+        const = 1 / sc
+    in const * exp_y * (exp $ - exp_y)
+
+quantileGumbel :: GumbelDistribution -> Double -> Double
+quantileGumbel (Gumbel loc sc) x
+    | x == 0         = -inf
+    | x == 1         = inf
+    | x > 0 && x < 1 = loc - sc * (log $ - log x)
+    | otherwise      =
+        error $ "Gev.GumbelDistribution.quantile: The given value must be between 0 and 1, got: " ++ show x
+    where inf = 1 / 0
+
+-- | Gev.Distribution instance implementation for the Gumbel Distribution
+instance Gev.Distribution GumbelDistribution where
+    cdf      = cdfGumbel
+    pdf      = pdfGumbel
+    quantile = quantileGumbel
diff --git a/src/Gev/Weibull.hs b/src/Gev/Weibull.hs
new file mode 100644
--- /dev/null
+++ b/src/Gev/Weibull.hs
@@ -0,0 +1,72 @@
+module Gev.Weibull
+    (
+      WeibullDistribution
+     -- * constructors
+    , weibullDist
+    , weibullDistMaybe
+     -- * accessors
+    , location
+    , scale
+    , shape
+    ) where
+
+import qualified Gev
+
+data WeibullDistribution = Weibull {
+      location :: {-# UNPACK #-} !Double
+    , scale    :: {-# UNPACK #-} !Double
+    , shape    :: {-# UNPACK #-} !Double
+    } deriving (Eq)
+
+instance Show WeibullDistribution where
+    show (Weibull loc sc sh) = show "Weibull Distribution; loc: " ++ show loc ++ ", scale: " ++ show sc ++ " and shape: " ++ show sh
+
+-- error message when initiating Weibull with scale and/or shape parameter less than 0.
+weibullErrMsg :: Double -> Double -> Double -> String
+weibullErrMsg loc scale sh = "Gev.Weibull: " 
+    ++ "loc = " ++ show loc
+    ++ " scale = " ++ show scale
+    ++ " schape = " ++ show sh
+    ++ ", but both the scale and shape parameters must be positive!"
+
+weibullDistMaybe :: Double -> Double -> Double -> Maybe WeibullDistribution
+weibullDistMaybe loc sc sh
+    | sc > 0 && sh > 0 = Just $ Weibull loc sc sh
+    | otherwise = Nothing
+
+weibullDist :: Double -> Double -> Double -> WeibullDistribution
+weibullDist loc sc sh = maybe (error $ weibullErrMsg loc sc sh) id $ weibullDistMaybe loc sh sc
+
+-- | The CDF of the Weibull distribution
+cdfWeibull :: WeibullDistribution -> Double -> Double
+cdfWeibull (Weibull loc sc sh) x
+    | x <= 0     = 0
+    | otherwise  = exp $ - ((- y) ** sh)
+        where 
+            y   = (x - loc) / sc
+
+-- | The PDF of the Weibull distribution
+pdfWeibull :: WeibullDistribution -> Double -> Double
+pdfWeibull (Weibull loc sc sh) x =
+    let y       = (x - loc) / sc
+        const   = sh / sc
+        expterm = exp $ - ((- y) ** sh)
+        middle  = (- y) ** (sh - 1)
+    in const * middle * expterm
+
+quantileWeibull :: WeibullDistribution -> Double -> Double
+quantileWeibull (Weibull loc sc sh) x
+    | x == 0          = -inf
+    | x == 1          = inf
+    | x > 0 && x < 1  = loc - sc * (logexp ** pow)
+    | otherwise       =
+        error $ "Gev.WeibullDistribution.quantile: The given value must be between 0 and 1, got: " ++ show x
+    where
+        inf    = 1 / 0
+        logexp = - log x
+        pow    = 1 / sh
+
+instance Gev.Distribution WeibullDistribution where
+    pdf      = pdfWeibull
+    cdf      = cdfWeibull
+    quantile = quantileWeibull
diff --git a/src/Tests/tests.hs b/src/Tests/tests.hs
new file mode 100644
--- /dev/null
+++ b/src/Tests/tests.hs
@@ -0,0 +1,119 @@
+-- | tests for the library
+
+module Main where
+
+import Gev
+import Gev.Gumbel
+import Gev.Frechet
+import Gev.Weibull
+import Gev.GevDist
+
+import Test.HUnit
+import qualified System.Exit as Exit
+
+------------------------------------ Gumbel ------------------------------------
+
+-- | Gumbel dist instance.
+gumbel :: GumbelDistribution
+gumbel = gumbelDist 0.5 2.0
+
+-- | individual test
+testGumbelCDF :: Test
+testGumbelCDF = TestCase (assertEqual "Gumbel CDF test" 0.6235249162568004 (cdf gumbel 2.0))
+
+testGumbelPDF :: Test
+testGumbelPDF = TestCase (assertEqual "Gumbel PDF test" 0.14726615762017733 (pdf gumbel 2.0))
+
+testGumbelQuant :: Test
+testGumbelQuant = TestCase (assertEqual "Gumbel Qauntile test" 2.5618608663174456 (quantile gumbel 0.7))
+
+------------------------------------ Frechet -----------------------------------
+
+-- | Frechet dist instance.
+frechet :: FrechetDistribution
+frechet = frechetDist 1.0 0.1 1.0
+
+-- | individual test
+testFrechetCDF :: Test
+testFrechetCDF = TestCase (assertEqual "Frechet CDF test" 0.951229424500714 (cdf frechet 3.0))
+
+testFrechetPDF :: Test
+testFrechetPDF = TestCase (assertEqual "Frechet PDF test" 0.023780735612517853 (pdf frechet 3.0))
+
+testFrechetQuant :: Test
+testFrechetQuant = TestCase (assertEqual "Frechet Qauntile test" 1.2803673252057128 (quantile frechet 0.7))
+
+------------------------------------ Weibull -----------------------------------
+
+-- | Weibull dist instance.
+weibull :: WeibullDistribution
+weibull = weibullDist 2.0 2.0 2.0
+
+-- | individual test
+testWeibullCDF :: Test
+testWeibullCDF = TestCase (assertEqual "Weibull CDF test" 0.7788007830714049 (cdf weibull 1.0))
+
+testWeibullPDF :: Test
+testWeibullPDF = TestCase (assertEqual "Weibull PDF test" 0.38940039153570244 (pdf weibull 1.0))
+
+testWeibullQuant :: Test
+testWeibullQuant = TestCase (assertEqual "Weibull Qauntile test" 0.8055546158342233 (quantile weibull 0.7))
+
+
+------------------------------------ GEV -----------------------------------
+
+--------- GEV with shape not equal to 0
+
+-- | GEV dist instance.
+gev :: GevDistribution
+gev = gevDist 2.0 2.0 2.0
+
+-- | individual test
+testGEVCDF :: Test
+testGEVCDF = TestCase (assertEqual "GEV CDF test" 0.4930686913952398 (cdf gev 3.0))
+
+testGEVPDF :: Test
+testGEVPDF = TestCase (assertEqual "GEV PDF test" 0.0871630538190878 (pdf gev 3.0))
+
+testGEVQuant :: Test
+testGEVQuant = TestCase (assertEqual "GEV Qauntile test" 8.860583704300595 (quantile gev 0.7))
+
+
+--------- GEV with shape equal to 0
+
+-- | GEV dist instance with shape equal to 0.
+gevAlt :: GevDistribution
+gevAlt = gevDist 2.0 2.0 0.0
+
+-- | individual test
+testGEVCDFAlt :: Test
+testGEVCDFAlt = TestCase (assertEqual "GEV CDF test" 0.545239211892605 (cdf gevAlt 3.0))
+
+testGEVPDFAlt :: Test
+testGEVPDFAlt = TestCase (assertEqual "GEV PDF test" 0.16535214944520904 (pdf gevAlt 3.0))
+
+testGEVQuantAlt :: Test
+testGEVQuantAlt = TestCase (assertEqual "GEV Qauntile test" 4.061860866317446 (quantile gevAlt 0.7))
+
+-- | list of tests
+testList :: Test
+testList = TestList [ TestLabel "testGumbelCDF" testGumbelCDF
+                    , TestLabel "testGumbelPDF" testGumbelPDF
+                    , TestLabel "testGumbelQuant" testGumbelQuant
+                    , TestLabel "testFrechetCDF" testFrechetCDF
+                    , TestLabel "testFrechetPDF" testFrechetPDF
+                    , TestLabel "testFrechetQuant" testFrechetQuant
+                    , TestLabel "testWeibullCDF" testWeibullCDF
+                    , TestLabel "testWeibullPDF" testWeibullPDF
+                    , TestLabel "testWeibullQuant" testWeibullQuant
+                    , TestLabel "testGEVCDF" testGEVCDF
+                    , TestLabel "testGEVPDF" testGEVPDF
+                    , TestLabel "testGEVQuant" testGEVQuant
+                    , TestLabel "testGEVCDFAlt" testGEVCDFAlt
+                    , TestLabel "testGEVPDFAlt" testGEVPDFAlt
+                    , TestLabel "testGEVQuantAlt" testGEVQuantAlt]
+
+main :: IO ()
+main = do
+    result <- runTestTT testList
+    if failures result > 0 then Exit.exitFailure else Exit.exitSuccess
