diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2017 HE, Tao (sighingnow@gmail.com)
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,7 @@
+# primesieve
+
+FFI bindings for the primesieve library.
+
+## License
+
+Copyright (c) 2017 HE, Tao (sighingnow@gmail.com)
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/example/Main.hs b/example/Main.hs
new file mode 100644
--- /dev/null
+++ b/example/Main.hs
@@ -0,0 +1,16 @@
+module Main where
+
+import Foundation
+
+import Math.Prime.FastSieve
+
+main :: IO ()
+main = do
+    primesieveVersion >>= putStrLn . ("Version of primesieve: " <>)
+    
+    ns <- generateNPrimes 10 0 :: IO (UArray Int32)
+    putStrLn $ "The first 10 primes: " <> show ns
+
+    putStrLn $ "Count of primes between 100 and 1000000: " <> show (countPrimes 100 1000000)
+
+    putStrLn $ "The 12345678th prime number (from 0): " <> show (nthPrime 12345678 0)
diff --git a/primesieve.cabal b/primesieve.cabal
new file mode 100644
--- /dev/null
+++ b/primesieve.cabal
@@ -0,0 +1,37 @@
+name:                primesieve
+version:             0.1.0.0
+synopsis:            FFI bindings for the primesieve library.
+description:         FFI bindings for the primesieve library.
+homepage:            https://github.com/sighingnow/computations/tree/master/primesieve#readme
+author:              Tao He
+maintainer:          sighingnow@gmail.com
+copyright:           Copyright: (c) 2017 Tao He
+category:            Algorithms, Foreign, Math, Number Theory
+build-type:          Simple
+cabal-version:       >=1.10
+license:             MIT
+license-file:        LICENSE
+extra-source-files:  README.md
+
+library
+  hs-source-dirs:      src
+  exposed-modules:
+    Math.Prime.FastSieve
+  other-modules:
+    Math.Prime.FastSieve.FFI
+  default-language:    Haskell2010
+  default-extensions:  NoImplicitPrelude
+                     , OverloadedStrings
+  build-depends:       base >= 4.7 && < 5
+                     , foundation
+
+executable prime-example
+  hs-source-dirs:      example
+  main-is:             Main.hs
+  default-language:    Haskell2010
+  default-extensions:  NoImplicitPrelude
+                     , OverloadedStrings
+  build-depends:       base >= 4.7 && < 5
+                     , foundation
+                     , primesieve
+  extra-libraries:     primesieve
diff --git a/src/Math/Prime/FastSieve.hs b/src/Math/Prime/FastSieve.hs
new file mode 100644
--- /dev/null
+++ b/src/Math/Prime/FastSieve.hs
@@ -0,0 +1,23 @@
+module Math.Prime.FastSieve
+    ( generatePrimes
+    , generateNPrimes
+    , nthPrime
+    , countPrimes
+    , countTwins
+    , countTriplets
+    , countQuadruplets
+    , countQuintuplets
+    , countSextuplets
+    , printPrimes
+    , printTwins
+    , printTriplets
+    , printQuadruplets
+    , printQuintuplets
+    , printSextuplets
+    , getMaxStop
+    , setSieveSize
+    , setNumThreads
+    , primesieveVersion
+    ) where
+
+import Math.Prime.FastSieve.FFI
diff --git a/src/Math/Prime/FastSieve/FFI.hs b/src/Math/Prime/FastSieve/FFI.hs
new file mode 100644
--- /dev/null
+++ b/src/Math/Prime/FastSieve/FFI.hs
@@ -0,0 +1,252 @@
+{-# OPTIONS_GHC -Wno-missing-methods #-}
+{-# OPTIONS_GHC -Wno-missing-pattern-synonym-signatures #-}
+{-# OPTIONS_GHC -Wno-missing-signatures #-}
+{-# OPTIONS_GHC -Wno-orphans #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module Math.Prime.FastSieve.FFI where
+
+import Foundation
+import Foundation.Foreign
+import Foundation.Class.Storable
+import Foundation.String (fromBytesUnsafe)
+
+import Foreign.Marshal.Alloc (alloca)
+
+class (PrimType ty, StorableFixed ty) => Prime ty where
+    tcode :: Proxy ty -> CInt
+
+pattern SHORT = 0
+pattern USHORT = 1
+pattern INT = 2
+pattern UINT = 3
+pattern LONG = 4
+pattern ULONG = 5
+pattern LONGLONG = 6
+pattern ULONGLONG = 7
+pattern INT16 = 8
+pattern UINT16 = 9
+pattern INT32 = 10
+pattern UINT32 = 11
+pattern INT64 = 12
+pattern UINT64 = 13
+
+instance Prime Int16 where
+    tcode _ = INT16
+
+instance Prime Int32 where
+    tcode _ = INT32
+
+instance Prime Int64 where
+    tcode _ = INT64
+
+instance Prime Word16 where
+    tcode _ = UINT16
+
+instance Prime Word32 where
+    tcode _ = UINT32
+
+instance Prime Word64 where
+    tcode _ = UINT64
+
+-- | Orphan instance for CSize as Storable.
+instance Storable CSize
+
+foreign import ccall unsafe "primesieve_generate_primes" c_generate_primes
+    :: Word64 -> Word64 -> Ptr CSize -> CInt -> IO (Ptr ())
+
+foreign import ccall unsafe "primesieve_generate_n_primes" c_generate_n_primes
+    :: Word64 -> Word64 -> CInt -> IO (Ptr ())
+
+foreign import ccall unsafe "primesieve_nth_prime" c_nth_prime
+    :: Int64 -> Word64 -> Word64
+
+foreign import ccall unsafe "primesieve_count_primes" c_count_primes
+    :: Word64 -> Word64 -> Word64
+
+foreign import ccall unsafe "primesieve_count_twins" c_count_twins
+    :: Word64 -> Word64 -> Word64
+
+foreign import ccall unsafe "primesieve_count_triplets" c_count_triplets
+    :: Word64 -> Word64 -> Word64
+
+foreign import ccall unsafe "primesieve_count_quadruplets" c_count_quadruplets
+    :: Word64 -> Word64 -> Word64
+
+foreign import ccall unsafe "primesieve_count_quintuplets" c_count_quintuplets
+    :: Word64 -> Word64 -> Word64
+
+foreign import ccall unsafe "primesieve_count_sextuplets" c_count_sextuplets
+    :: Word64 -> Word64 -> Word64
+
+foreign import ccall unsafe "primesieve_print_primes" c_print_primes
+    :: Word64 -> Word64 -> IO ()
+
+foreign import ccall unsafe "primesieve_print_twins" c_print_twins
+    :: Word64 -> Word64 -> IO ()
+
+foreign import ccall unsafe "primesieve_print_triplets" c_print_triplets
+    :: Word64 -> Word64 -> IO ()
+
+foreign import ccall unsafe "primesieve_print_quadruplets" c_print_quadruplets
+    :: Word64 -> Word64 -> IO ()
+
+foreign import ccall unsafe "primesieve_print_quintuplets" c_print_quintuplets
+    :: Word64 -> Word64 -> IO ()
+
+foreign import ccall unsafe "primesieve_print_sextuplets" c_print_sextuplets
+    :: Word64 -> Word64 -> IO ()
+
+foreign import ccall unsafe "primesieve_get_max_stop" c_get_max_stop
+    :: Word64
+
+foreign import ccall unsafe "primesieve_set_sieve_size" c_set_sieve_size
+    :: CInt -> IO ()
+
+foreign import ccall unsafe "primesieve_set_num_threads" c_set_num_threads
+    :: CInt -> IO ()
+
+-- | Deallocate a primes array created using the primesieve_generate_primes() or primesieve_generate_n_primes()
+foreign import ccall unsafe "primesieve_free" c_primesieve_free
+    :: Ptr () -> IO ()
+
+foreign import ccall unsafe "primesieve_version" c_version
+    :: IO (Ptr Word8)
+
+-- | Get an array with the primes inside the interval [start, stop].
+generatePrimes :: forall ty. Prime ty
+    => Word64           -- ^ start
+    -> Word64           -- ^ end
+    -> IO (UArray ty)
+generatePrimes start end = alloca $ \psz -> do
+    p <- c_generate_primes start end psz (tcode (Proxy :: Proxy ty))
+    sz <- peek psz
+    arr <- peekArray (CountOf . fromIntegral $ sz) (castPtr p)
+    c_primesieve_free p -- free the memory allocated by primesieve.
+    return arr
+
+-- | Get an array with the first n primes >= start.
+generateNPrimes :: forall ty. Prime ty
+    => Word64           -- ^ n
+    -> Word64           -- ^ start
+    -> IO (UArray ty)
+generateNPrimes n start = do
+    p <- c_generate_n_primes n start (tcode (Proxy :: Proxy ty))
+    arr <- peekArray (CountOf . fromIntegral $ n) (castPtr p)
+    c_primesieve_free p -- free the memory allocated by primesieve.
+    return arr
+
+-- | Find the nth prime.
+--
+--      * if n = 0 finds the 1st prime >= start,
+--      * if n > 0 finds the nth prime > start,
+--      * if n < 0 finds the nth prime < start (backwards).
+nthPrime ::
+       Int64    -- ^ n
+    -> Word64   -- ^ start
+    -> Word64
+nthPrime = c_nth_prime
+
+-- | Count the primes within the interval [start, stop].
+countPrimes ::
+       Word64   -- ^ start
+    -> Word64   -- ^ end
+    -> Word64
+countPrimes = c_count_primes
+
+-- | Count the twins within the interval [start, stop].
+countTwins ::
+       Word64   -- ^ start
+    -> Word64   -- ^ end
+    -> Word64
+countTwins = c_count_twins
+
+-- | Count the triplets within the interval [start, stop].
+countTriplets ::
+       Word64   -- ^ start
+    -> Word64   -- ^ end
+    -> Word64
+countTriplets = c_count_triplets
+
+-- | Count the quadruplets within the interval [start, stop].
+countQuadruplets ::
+       Word64   -- ^ start
+    -> Word64   -- ^ end
+    -> Word64
+countQuadruplets = c_count_quadruplets
+
+-- | Count the quintuplets within the interval [start, stop].
+countQuintuplets ::
+       Word64   -- ^ start
+    -> Word64   -- ^ end
+    -> Word64
+countQuintuplets = c_count_quintuplets
+
+-- | Count the sextuplets within the interval [start, stop].
+countSextuplets ::
+       Word64   -- ^ start
+    -> Word64   -- ^ end
+    -> Word64
+countSextuplets = c_count_sextuplets
+
+-- | Print the primes within the interval [start, stop] to the standard output.
+printPrimes ::
+       Word64   -- ^ start
+    -> Word64   -- ^ end
+    -> IO ()
+printPrimes = c_print_primes
+
+-- | Print the prime twins within the interval [start, stop] to the standard output.
+printTwins ::
+       Word64   -- ^ start
+    -> Word64   -- ^ end
+    -> IO ()
+printTwins = c_print_twins
+
+-- | Print the prime triplets within the interval [start, stop] to the standard output.
+printTriplets ::
+       Word64   -- ^ start
+    -> Word64   -- ^ end
+    -> IO ()
+printTriplets = c_print_triplets
+
+-- | Print the prime quadruplets within the interval [start, stop] to the standard output.
+printQuadruplets ::
+       Word64   -- ^ start
+    -> Word64   -- ^ end
+    -> IO ()
+printQuadruplets = c_print_quadruplets
+
+-- | Print the prime quintuplets within the interval [start, stop] to the standard output.
+printQuintuplets ::
+       Word64   -- ^ start
+    -> Word64   -- ^ end
+    -> IO ()
+printQuintuplets = c_print_quintuplets
+
+-- | Print the prime sextuplets within the interval [start, stop] to the standard output.
+printSextuplets ::
+       Word64   -- ^ start
+    -> Word64   -- ^ end
+    -> IO ()
+printSextuplets = c_print_sextuplets
+
+-- | Returns the largest valid stop number for primesieve, 2^64-1 (UINT64_MAX).
+getMaxStop :: Word64
+getMaxStop = c_get_max_stop
+
+-- | Set the sieve size in kilobytes.
+-- The best sieving performance is achieved with a sieve size of your CPU's L1 or L2 cache size (per core).
+setSieveSize :: Int -> IO ()
+setSieveSize = c_set_sieve_size . fromIntegral
+
+-- | Set the number of threads for use in primesieve_count_*() and primesieve_nth_prime().
+-- By default all CPU cores are used.
+setNumThreads :: Int -> IO ()
+setNumThreads = c_set_num_threads . fromIntegral
+
+-- | Get the primesieve version number, in the form "i.j".
+primesieveVersion :: IO String
+primesieveVersion = c_version >>= (fromBytesUnsafe <$>) . peekArrayEndedBy 0
