diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 Kadzuya OKAMOTO, http://www.arow.info
+
+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,13 @@
+[![Build Status](https://travis-ci.org/arowM/haskell-bookkeeping.svg?branch=master)](https://travis-ci.org/arowM/heterocephalus)
+
+# Haskell-bookkeeping
+
+A module for bookkeeping by double entry. This module provides a way to do bookkeeping programmatically.
+
+## Example
+
+TODO
+
+## Export as CSV
+
+TODO
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/bookkeeping.cabal b/bookkeeping.cabal
new file mode 100644
--- /dev/null
+++ b/bookkeeping.cabal
@@ -0,0 +1,54 @@
+name:                bookkeeping
+version:             0.1.0.1
+synopsis:            A module for bookkeeping by double entry.
+description:
+    A module for bookkeeping by double entry. This module provides a way to do bookkeeping programmatically.
+homepage:            https://github.com/arowM/haskell-bookkeeping#readme
+license:             MIT
+license-file:        LICENSE
+author:              Kadzuya Okamoto
+maintainer:          arow.okamoto+github@gmail.com
+copyright:           2017 Kadzuya Okamoto
+category:            Business
+build-type:          Simple
+extra-source-files:  README.md
+cabal-version:       >=1.10
+
+library
+  hs-source-dirs:      src
+  exposed-modules:     Business.Bookkeeping
+  build-depends:       base >= 4.9 && < 4.10
+                     , dlist >= 0.8.0.2 && < 0.9
+                     , mtl >= 2.2.1 && < 2.3
+                     , text >= 1.2.2.1 && < 1.3
+                     , time >= 1.6.0.1 && < 1.7
+  default-language:    Haskell2010
+  default-extensions:  OverloadedStrings
+                     , RecordWildCards
+                     , Strict
+                     , StrictData
+  other-extensions:    GeneralizedNewtypeDeriving
+
+test-suite bookkeeping-test
+  type:                exitcode-stdio-1.0
+  hs-source-dirs:      test
+  main-is:             Spec.hs
+  build-depends:       base
+                     , bookkeeping
+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
+  default-language:    Haskell2010
+
+test-suite doctest
+  type:                exitcode-stdio-1.0
+  hs-source-dirs:      test
+  main-is:             Doctest.hs
+  build-depends:       base
+                     , Glob
+                     , doctest >= 0.10
+                     , bookkeeping
+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
+  default-language:    Haskell2010
+
+source-repository head
+  type:     git
+  location: https://github.com/arowM/haskell-bookkeeping
diff --git a/src/Business/Bookkeeping.hs b/src/Business/Bookkeeping.hs
new file mode 100644
--- /dev/null
+++ b/src/Business/Bookkeeping.hs
@@ -0,0 +1,249 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+
+{- |
+Module      :  Business.Bookkeeping
+
+Copyright   :  Kadzuya Okamoto 2017
+License     :  MIT
+
+Stability   :  experimental
+Portability :  unknown
+
+This module exports core functions and types for bookkeeping.
+-}
+module Business.Bookkeeping
+  (
+  -- * Usage examples
+  -- $setup
+
+  -- * Pritty printers
+    ppr
+
+  -- * Constructors
+  , year
+  , month
+  , activity
+  , dateTrans
+
+  -- * Converters
+  , runTransactions
+
+  -- * Types
+  , Transactions
+  , YearTransactions
+  , MonthTransactions
+  , DateTransactions
+  , Transaction(..)
+  , Year(..)
+  , Month(..)
+  , Date(..)
+  , Description(..)
+  , Amount(..)
+  , Category(..)
+  , CategoryName(..)
+  , CategoryType(..)
+  , DebitCategory(..)
+  , CreditCategory(..)
+  ) where
+
+import Control.Monad.State (State, execState, modify)
+import qualified Data.DList as DList
+import Data.DList (DList)
+import Data.Monoid ((<>))
+import Data.String (IsString(..))
+import Data.Text (Text)
+import qualified Data.Text as T
+import qualified Data.Text.IO as T
+import Data.Time.Calendar (Day, fromGregorian)
+
+{- $setup
+>>> :{
+let
+  advance :: CategoryName -> Description -> Amount -> DateTransactions
+  advance name = dateTrans
+    (DebitCategory $ Category name Expenses)
+    (CreditCategory $ Category "Deposit" Assets)
+  sample =
+    year 2015 $ do
+      month 1 $ do
+        activity 1 "Constant expenses --" $
+          advance "Communication" "Mobile phone" 3000
+        activity 3 "Mail a contract --" $ do
+          advance "Communication" "Stamp" 50
+          advance "Office supplies" "Envelope" 100
+      month 2 $
+        activity 1 "Constant expenses --" $
+          advance "Communication" "Mobile phone" 3000
+:}
+-}
+{-| Convert from 'YearTransactions' to 'Transactions'.
+-}
+year :: Year -> YearTransactions -> Transactions
+year y =
+  modify . flip mappend . fmap ($ y) . toDList
+
+{-| Convert from 'MonthTransactions' to 'YearTransactions'.
+-}
+month :: Month -> MonthTransactions -> YearTransactions
+month m =
+  modify . flip mappend . fmap ($ m) . toDList
+
+{-| Convert from 'DateTransactions' to 'MonthTransactions'.
+-}
+activity :: Date -> Description -> DateTransactions -> MonthTransactions
+activity d desc =
+  modify . flip mappend . fmap (($ desc) . ($ d)) . toDList
+
+dateTrans :: DebitCategory
+          -> CreditCategory
+          -> Description
+          -> Amount
+          -> DateTransactions
+dateTrans debit credit desc amount =
+  modify . flip mappend . DList.singleton $ \d desc' m y ->
+    Transaction
+    { tDay = fromGregorian (unYear y) (unMonth m) (unDate d)
+    , tDescription = desc' <> " " <> desc
+    , tDebit = debit
+    , tCredit = credit
+    , tAmount = amount
+    }
+
+{-| Take list of `Transaction` out from 'Transactions'.
+-}
+runTransactions :: Transactions -> [Transaction]
+runTransactions = DList.toList . toDList
+
+toDList :: Trans a -> DList a
+toDList ts = execState ts mempty
+
+{-| A pretty printer for `Transactions`.
+
+>>> ppr sample
+tDay: 2015-01-01
+tDescription: Constant expenses -- Mobile phone
+tDebit: Communication (Expenses)
+tCredit: Deposit (Assets)
+tAmount: 3000
+<BLANKLINE>
+tDay: 2015-01-03
+tDescription: Mail a contract -- Stamp
+tDebit: Communication (Expenses)
+tCredit: Deposit (Assets)
+tAmount: 50
+<BLANKLINE>
+tDay: 2015-01-03
+tDescription: Mail a contract -- Envelope
+tDebit: Office supplies (Expenses)
+tCredit: Deposit (Assets)
+tAmount: 100
+<BLANKLINE>
+tDay: 2015-02-01
+tDescription: Constant expenses -- Mobile phone
+tDebit: Communication (Expenses)
+tCredit: Deposit (Assets)
+tAmount: 3000
+<BLANKLINE>
+-}
+ppr :: Transactions -> IO ()
+ppr = T.putStr . T.unlines . map format . runTransactions
+  where
+    format :: Transaction -> T.Text
+    format Transaction {..} =
+      T.unlines
+        [ "tDay: " <> (T.pack . show) tDay
+        , "tDescription: " <> unDescription tDescription
+        , "tDebit: " <> (unCategoryName . cName . unDebitCategory) tDebit <>
+          " (" <>
+          (T.pack . show . cType . unDebitCategory) tDebit <>
+          ")"
+        , "tCredit: " <> (unCategoryName . cName . unCreditCategory) tCredit <>
+          " (" <>
+          (T.pack . show . cType . unCreditCategory) tCredit <>
+          ")"
+        , "tAmount: " <> (T.pack . show . unAmount) tAmount
+        ]
+
+
+{- ==============
+ -     Types
+ - ============== -}
+
+type Trans a = State (DList a) ()
+
+{-| A type for handling `Transaction` values.
+ -}
+type Transactions = Trans Transaction
+
+type YearTransactions = Trans (Year -> Transaction)
+
+type MonthTransactions = Trans (Month -> Year -> Transaction)
+
+type DateTransactions = Trans (Date -> Description -> Month -> Year -> Transaction)
+
+{-| A type representing a transaction.
+ -}
+data Transaction = Transaction
+  { tDay :: Day
+  , tDescription :: Description
+  , tDebit :: DebitCategory
+  , tCredit :: CreditCategory
+  , tAmount :: Amount
+  } deriving (Show, Read, Ord, Eq)
+
+newtype Year = Year
+  { unYear :: Integer
+  } deriving (Show, Read, Ord, Eq, Num)
+
+newtype Month = Month
+  { unMonth :: Int
+  } deriving (Show, Read, Ord, Eq, Num)
+
+newtype Date = Date
+  { unDate :: Int
+  } deriving (Show, Read, Ord, Eq, Num)
+
+newtype Description = Description
+  { unDescription :: Text
+  } deriving (Show, Read, Ord, Eq)
+
+instance IsString Description where
+  fromString = Description . fromString
+
+instance Monoid Description where
+  mempty = Description mempty
+  mappend (Description a) (Description b) = Description $ mappend a b
+
+newtype Amount = Amount
+  { unAmount :: Int
+  } deriving (Show, Read, Ord, Eq, Num)
+
+newtype DebitCategory = DebitCategory
+  { unDebitCategory :: Category
+  } deriving (Show, Read, Ord, Eq)
+
+newtype CreditCategory = CreditCategory
+  { unCreditCategory :: Category
+  } deriving (Show, Read, Ord, Eq)
+
+{-| A type representing an accounts title.
+ -}
+data Category = Category
+  { cName :: CategoryName
+  , cType :: CategoryType
+  } deriving (Show, Read, Ord, Eq)
+
+newtype CategoryName = CategoryName
+  { unCategoryName :: Text
+  } deriving (Show, Read, Ord, Eq)
+
+instance IsString CategoryName where
+  fromString = CategoryName . fromString
+
+data CategoryType
+  = Assets
+  | Liabilities
+  | Stock
+  | Revenue
+  | Expenses
+  deriving (Show, Read, Ord, Eq, Enum)
diff --git a/test/Doctest.hs b/test/Doctest.hs
new file mode 100644
--- /dev/null
+++ b/test/Doctest.hs
@@ -0,0 +1,19 @@
+module Main where
+
+import Data.Monoid ((<>))
+import System.FilePath.Glob (glob)
+import Test.DocTest (doctest)
+
+main :: IO ()
+main = glob "src/**/*.hs" >>= doDocTest
+
+doDocTest :: [String] -> IO ()
+doDocTest options = doctest $ options <> ghcExtensions
+
+ghcExtensions :: [String]
+ghcExtensions =
+    [ "-XOverloadedStrings"
+    , "-XRecordWildCards"
+    , "-XStrict"
+    , "-XStrictData"
+    ]
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,2 @@
+main :: IO ()
+main = putStrLn "Test suite not yet implemented"
