diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Kostiantyn Rybnikov (c) 2018
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Kostiantyn Rybnikov nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,9 @@
+# sentiwordnet-parser
+
+Parser for the [SentiWordNet](http://sentiwordnet.isti.cnr.it/) tab-separated file.
+
+See docs at http://hackage.haskell.org/package/sentiwordnet-parser
+
+TODO:
+
+- [ ] reimplement via attoparsec for better speed
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/sentiwordnet-parser.cabal b/sentiwordnet-parser.cabal
new file mode 100644
--- /dev/null
+++ b/sentiwordnet-parser.cabal
@@ -0,0 +1,41 @@
+-- This file has been generated from package.yaml by hpack version 0.20.0.
+--
+-- see: https://github.com/sol/hpack
+--
+-- hash: e874425ac4cd0dc77602bc63619c082712827ce8371eec6e0646730a66c3bcd2
+
+name:           sentiwordnet-parser
+version:        0.1.0.0
+synopsis:       Parser for the SentiWordNet tab-separated file
+description:    Parser for the SentiWordNet tab-separated file
+category:       Natural Language Processing
+homepage:       https://github.com/k-bx/sentiwordnet-parser#readme
+author:         Kostiantyn Rybnikov
+maintainer:     k-bx@k-bx.com
+copyright:      All Rights Reserved
+license:        BSD3
+license-file:   LICENSE
+build-type:     Simple
+cabal-version:  >= 1.10
+
+extra-source-files:
+    README.md
+
+library
+  hs-source-dirs:
+      src
+  ghc-options: -Wall
+  build-depends:
+      Decimal
+    , base >=4.7 && <5
+    , parsers
+    , safe
+    , string-class
+    , text
+    , trifecta
+    , vector
+  exposed-modules:
+      NLP.SentiwordnetParser
+  other-modules:
+      Paths_sentiwordnet_parser
+  default-language: Haskell2010
diff --git a/src/NLP/SentiwordnetParser.hs b/src/NLP/SentiwordnetParser.hs
new file mode 100644
--- /dev/null
+++ b/src/NLP/SentiwordnetParser.hs
@@ -0,0 +1,117 @@
+{-# LANGUAGE ApplicativeDo #-}
+{-# LANGUAGE RecordWildCards #-}
+
+module NLP.SentiwordnetParser
+  ( parse
+  , SentiWordNet(..)
+  , Entry(..)
+  , SynsetTerm(..)
+  , POS(..)
+  -- * internal stuff
+  , parseSentiWordNet
+  , parsePOS
+  , parseDecimal
+  , parseInt
+  , parseEntry
+  , parseSynsetTerm
+  , parseComment
+  , test
+  ) where
+
+import Control.Applicative
+import Data.Decimal (Decimal)
+import Data.Text (Text)
+import qualified Data.Text as T
+import qualified Data.Text.IO as T
+import Safe
+import Text.Trifecta
+
+data SynsetTerm = SynsetTerm
+  { name :: Text
+  , num :: Int
+  } deriving (Show, Eq)
+
+data POS
+  = Noun
+  | Verb
+  | Adjective
+  | AdjectiveSatellite
+  | Adverb
+  deriving (Show, Eq)
+
+data Entry = Entry
+  { pos :: POS
+  , id_ :: Text
+  , posScore :: Decimal
+  , negScore :: Decimal
+  , synsetTerms :: [SynsetTerm]
+  , gloss :: Text
+  } deriving (Show, Eq)
+
+data SentiWordNet = SentiWordNet
+  { items :: [Entry]
+  } deriving (Show, Eq)
+
+parsePOS :: Parser POS
+parsePOS =
+  pure Noun <* char 'n' <|> pure Verb <* char 'v' <|> pure Adjective <* char 'a' <|>
+  pure AdjectiveSatellite <* char 's' <|>
+  pure Adverb <* char 'r'
+
+parseInt :: Parser Int
+parseInt = do
+  s <- many alphaNum
+  case readMay s of
+    Nothing -> fail ("Failed to read an int: " ++ s)
+    Just res -> return res
+
+parseDecimal :: Parser Decimal
+parseDecimal = do
+  s <- many (alphaNum <|> char '.')
+  let r = readMay s
+  case r of
+    Nothing -> fail ("Failed to read decimal: " ++ s)
+    Just res -> return res
+
+parseSynsetTerm :: Parser SynsetTerm
+parseSynsetTerm = do
+  name <- T.pack <$> many (noneOf ['#'])
+  _ <- char '#'
+  num <- parseInt
+  return SynsetTerm {..}
+
+parseEntry :: Parser Entry
+parseEntry = do
+  _ <- optional (many parseComment)
+  pos <- parsePOS
+  _ <- tab
+  id_ <- T.pack <$> many (noneOf ['\t'])
+  _ <- tab
+  posScore <- parseDecimal
+  _ <- tab
+  negScore <- parseDecimal
+  _ <- tab
+  synsetTerms <- sepBy parseSynsetTerm (char ' ')
+  _ <- tab
+  gloss <- T.pack <$> many (noneOf ['\r', '\n'])
+  _ <- optional newline
+  return (Entry {..})
+
+parseComment :: Parser String
+parseComment = char '#' *> many (noneOf ['\n']) <* optional newline
+
+parseSentiWordNet :: Parser SentiWordNet
+parseSentiWordNet = SentiWordNet <$> some parseEntry
+
+parse :: Text -> Result SentiWordNet
+parse = parseString parseSentiWordNet mempty . T.unpack
+
+test :: IO ()
+test = do
+  sentiWordNet <-
+    T.readFile
+      "/home/kb/Downloads/SentiWordNet_3.0.0/SentiWordNet_3.0.0_20130122.txt"
+  let res = parse sentiWordNet
+  case res of
+    Success r -> print (length (items r))
+    Failure e -> print e
