diff --git a/.gitignore b/.gitignore
new file mode 100644
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,36 @@
+# my
+ignore/
+notes
+goals
+TODO
+cbits/main
+.projectile
+result/
+result
+
+# Haskell
+dist
+cabal-dev
+*.o
+*.hi
+*.chi
+*.chs.h
+.virtualenv
+.hsenv
+.cabal-sandbox/
+cabal.sandbox.config
+cabal.config
+report.html
+.stack-work/
+
+# Emacs
+\#*
+*~
+.#*
+\#*\#
+*.log
+TAGS
+
+# OS X
+.DS_Store
+
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,14 @@
+# https://docs.travis-ci.com/user/languages/haskell
+
+#   - 8.0
+ghc:
+  - 7.10
+  - 7.8
+
+# install: stack install
+
+# script: stack test
+
+notifications:
+  email:
+    - samboosalis@gmail.com
diff --git a/HLint.hs b/HLint.hs
new file mode 100644
--- /dev/null
+++ b/HLint.hs
@@ -0,0 +1,9 @@
+{-# LANGUAGE PackageImports, TemplateHaskell #-}
+import "hint" HLint.Default
+import "hint" HLint.Dollar
+import "hint" HLint.Generalise
+ignore "Use unwords"
+ignore "Use map once"
+ignore "Use =<<"
+ignore "Functor law"
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,31 @@
+Copyright Spiros Boosalis (c) 2015
+
+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 Spiros Boosalis 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,8 @@
+[![Build Status](https://secure.travis-ci.org/sboosali/spiros.svg)](http://travis-ci.org/sboosali/spiros)
+[![Hackage](https://img.shields.io/hackage/v/spiros.svg)](https://hackage.haskell.org/package/spiros)
+
+# spiros
+
+my custom prelude
+
+[reverse dependencies](http://packdeps.haskellers.com/reverse/spiros)
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,3 @@
+import Distribution.Simple
+main = defaultMain
+
diff --git a/sources/Digit.hs b/sources/Digit.hs
new file mode 100644
--- /dev/null
+++ b/sources/Digit.hs
@@ -0,0 +1,37 @@
+{-# LANGUAGE LambdaCase, OverloadedStrings #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving, DeriveGeneric, DeriveDataTypeable #-}
+module Digit where
+import Prelude.Spiros
+
+import Data.Word (Word8)
+import GHC.Exts (IsString)
+
+newtype Digit = Digit Word8       -- TODO modular arithmetic: type Digit = Natural `Mod` 10
+ deriving (Show,Read,Eq,Ord,Generic,Data,NFData,Hashable)
+
+instance Bounded Digit where
+ minBound = Digit 0
+ maxBound = Digit 9
+
+instance Enum Digit where
+ toEnum i
+  | minBound <= i && i <= maxBound = Digit (toEnum i)
+  | otherwise                      = error ("Digit.toEnum: " ++ show i ++ " is not a single-digit integer")
+ fromEnum (Digit i) = fromEnum i
+
+parseDigit :: (IsString s, Eq s) => s -> Maybe Digit
+parseDigit = \case
+ "0" -> Just $ Digit 0
+ "1" -> Just $ Digit 1
+ "2" -> Just $ Digit 2
+ "3" -> Just $ Digit 3
+ "4" -> Just $ Digit 4
+ "5" -> Just $ Digit 5
+ "6" -> Just $ Digit 6
+ "7" -> Just $ Digit 7
+ "8" -> Just $ Digit 8
+ "9" -> Just $ Digit 9
+ _   -> Nothing
+
+isDigit :: (Integral a) => a -> Maybe Digit
+isDigit i = if 0 >= i && i <= 9 then Just (Digit (fromIntegral i)) else Nothing
diff --git a/sources/Prelude/Spiros.hs b/sources/Prelude/Spiros.hs
new file mode 100644
--- /dev/null
+++ b/sources/Prelude/Spiros.hs
@@ -0,0 +1,78 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+
+{-|
+
+exports:
+
+* single-character composition, i.e. ('>') an ('<')
+* universally (or frequently) derived classes,
+i.e. @deriving (...,'Data','Generic','NFData','Semigroup')@
+* and more (see source)
+
+hides:
+
+* partial functions, e.g. 'head'
+
+see:
+
+* <http://www.stephendiehl.com/posts/protolude.html>
+
+-}
+module Prelude.Spiros
+ ( module Base
+ , module X -- re-eXports
+ )
+where
+
+import Spiros.Utilities as X
+
+import Data.Hashable   as X (Hashable(..))
+import Control.DeepSeq as X (NFData(..))
+import Data.Semigroup  as X (Semigroup(..))
+import Safe            as X
+import Data.Text.Lazy  as X (Text)
+import Data.Default.Class as X (Default(..))
+
+import GHC.Generics    as X (Generic)
+import Data.Data       as X (Data)
+import Data.Function   as X ((&),on)
+import Data.Foldable   as X (traverse_)
+import Control.Arrow   as X ((>>>),(<<<))
+import Data.Set        as X (Set)
+import Data.Map        as X (Map)
+import Numeric.Natural as X (Natural)
+import Data.Proxy      as X (Proxy(..))
+import Control.Monad.IO.Class as X (MonadIO(..))
+import Control.Applicative as X
+
+#if MIN_VERSION_base(4,8,0)
+#else
+import Data.Functor as X ((<$>))
+import Data.Monoid as X (Monoid(..))
+#endif
+
+import Data.List as Base hiding
+ ( minimumBy
+ , maximumBy
+ , (!!)
+ , find
+ )
+
+import Prelude as Base hiding
+ ( (<), (>)
+ -- partials
+ , error, undefined
+ , tail
+ , init
+ , head
+ , last
+ , minimum
+ , maximum
+ , foldr1
+ , foldl1
+ , foldl1
+ , scanl1
+ , scanr1
+ , read
+ , toEnum
+ )
diff --git a/sources/Spiros/Utilities.hs b/sources/Spiros/Utilities.hs
new file mode 100644
--- /dev/null
+++ b/sources/Spiros/Utilities.hs
@@ -0,0 +1,232 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+{-# LANGUAGE RankNTypes, TypeOperators, LambdaCase, PatternSynonyms #-}
+{-# LANGUAGE PolyKinds, KindSignatures, ConstraintKinds #-}
+{-# OPTIONS_HADDOCK not-home #-}
+
+module Spiros.Utilities where
+
+import Data.Vinyl.Functor
+
+import Data.Functor.Product
+import Control.Arrow ((>>>),(<<<))
+import Control.Exception (SomeException)
+import Control.Concurrent (threadDelay,forkIO,ThreadId)
+import Control.Monad.IO.Class
+import Control.Monad (forever, void)
+import Data.Proxy
+import Data.String(IsString)
+
+import Prelude hiding ((<),(>))
+import qualified Prelude
+
+{-| for `interpolatedstring-perl6`
+i.e. the type supports string literals (via 'IsString') and can be appended (via 'Monoid').
+
+uses @ConstraintKinds@.
+
+e.g.
+
+@
+-- -XQuasiQuotes
+import Text.InterpolatedString.Perl6 (qq)
+
+hello :: (CanInterpolate t) => t -> t
+hello t = [qc| "hello" ++ $t |]
+
+helloworld = hello "world" :: String
+@
+
+-}
+type CanInterpolate t = (IsString t, Monoid t)
+
+{- | forwards composition
+
+e.g. "f, then g, then h"
+
+@
+forwards x
+ = x
+ & f
+ > g
+ > h
+@
+
+same precedence/associativity as '.'
+
+-}
+(>) :: (a -> b) -> (b -> c) -> (a -> c)
+(>) = (>>>)
+infixr 9 >
+
+{- | backwards composition
+
+e.g. "h, after g, after f"
+
+@
+backwards x
+ = h
+ < g
+ < f
+ $ x
+@
+
+same precedence/associativity as '.'
+
+-}
+(<) :: (b -> c) -> (a -> b) -> (a -> c)
+(<) = (<<<)
+infixr 9 <
+
+-- NOTE
+-- infixr 1 <<<
+-- infixr 9 .
+-- function application (i.e. whitespace juxtaposition) is like: infixl 10 _
+-- infixr 0 $
+-- infixl 1 &
+
+-- | same precedence/associativity as "Prelude.<"
+lessThan :: Ord a => a -> a -> Bool
+lessThan = (Prelude.<)
+infix 4 `lessThan`
+
+-- | same precedence/associativity as "Prelude.>"
+greaterThan :: Ord a => a -> a -> Bool
+greaterThan = (Prelude.>)
+infix 4 `greaterThan`
+
+{- | @(-:) = (,)@
+
+fake dictionary literal syntax:
+
+@
+ [ "a"-: 1
+ , "b"-: 2
+ , "c"-: 1+2
+ ] :: [(String,Integer)]
+@
+
+-}
+(-:) :: a -> b -> (a,b)
+(-:) = (,)
+infix 1 -:
+
+todo :: a --TODO call stack
+todo = error "TODO"
+
+__BUG__ :: SomeException -> a --TODO callstack
+__BUG__ = error . show
+
+-- | (from vinyl)
+type I = Identity
+
+-- | (from vinyl)
+type C = Const
+
+type P = Proxy
+
+-- | a natural transformation
+type (:~>) f g = forall x. f x -> g x
+
+-- |
+type (:*:) = Product
+
+-- |
+type (f :. g) x = f (g x)
+
+-- | (from vinyl)
+type (:.:) = Compose
+
+pattern I :: a -> Identity a
+pattern I x = Identity x
+
+pattern C :: forall a (b :: k). a -> Const a b
+pattern C x = Const x
+
+pattern P :: forall (a :: k). Proxy a
+pattern P = Proxy
+
+pattern (:*:) :: f a -> g a -> Product f g a
+pattern f :*: g = (Pair f g)
+
+nothing :: (Monad m) => m ()
+nothing = return ()
+
+maybe2bool :: Maybe a -> Bool
+maybe2bool = maybe False (const True)
+
+maybe2either :: e -> Maybe a -> Either e a 
+maybe2either e = maybe (Left e) Right
+
+either2maybe :: Either e a -> Maybe a
+either2maybe = either (const Nothing) Just
+
+either2bool :: Either e a -> Bool
+either2bool = either (const False) (const True)
+
+maybe2list :: Maybe a -> [a]
+maybe2list = maybe [] (:[])
+
+list2maybe :: [a] -> Maybe a
+list2maybe = \case
+ [] -> Nothing
+ (x:_) -> Just x
+
+-- | reverse @cons@
+snoc :: [a] -> a -> [a]
+snoc xs x = xs ++ [x]
+
+-- | @($>) = flip ('<$')@
+($>) :: (Functor f) => f a -> b -> f b
+($>) = flip (<$)
+
+forkever_ :: IO () -> IO ()
+forkever_ = void . forkever Nothing
+
+forkever ::Maybe Int -> IO () -> IO ThreadId
+forkever t m = forkIO $ forever $ do
+  m
+  _delay
+  where
+  _delay = maybe nothing delayMilliseconds t
+
+delayMilliseconds :: (MonadIO m) => Int -> m ()
+delayMilliseconds = liftIO . threadDelay . (*1000)
+
+{-|
+
+(NOTE truncates large integral types).
+
+-}
+toInt :: (Integral a) => a -> Int
+toInt = toInteger >>> (id :: Integer -> Integer) >>> fromIntegral
+
+-- | safely-partial @(!)@
+index :: (Integral n) => [a] -> n -> Maybe a
+index [] _ = Nothing
+index (x:xs) n
+ | n == 0         = Just x
+ | n `lessThan` 0 = Nothing
+ | otherwise      = index xs (n-1)
+
+strip :: String -> String
+strip = rstrip . lstrip
+
+lstrip :: String -> String
+lstrip = dropWhile (`elem` (" \t\n\r"::String))
+
+rstrip :: String -> String
+rstrip = reverse . lstrip . reverse
+
+io :: MonadIO m => IO a -> m a
+io = liftIO
+
+-- | Infix flipped 'fmap'.
+--
+-- @
+-- ('<&>') = 'flip' 'fmap'
+-- @
+--
+-- NOTE: conflicts with the lens package 
+(<&>) :: Functor f => f a -> (a -> b) -> f b
+as <&> f = f <$> as
+{-# INLINE (<&>) #-}
diff --git a/spiros.cabal b/spiros.cabal
new file mode 100644
--- /dev/null
+++ b/spiros.cabal
@@ -0,0 +1,89 @@
+name:                spiros
+version:             0.0.0
+synopsis:            my custom prelude
+description:         my custom prelude. diverges from base's; adding, removing, and shadowing.
+homepage:            http://github.com/sboosali/spiros#readme
+license:             BSD3
+license-file:        LICENSE
+author:              Spiros Boosalis
+maintainer:          samboosalis@gmail.com
+copyright:           2016 Spiros Boosalis
+category:            TODO
+build-type:          Simple
+cabal-version:       >=1.10
+
+-- $ stack new PACKAGE spirosboosalis.hsfiles -p "module:MODULE"
+
+extra-source-files:
+  README.md
+  .gitignore
+  .travis.yml
+  HLint.hs
+  stack.yaml
+
+--data-files:
+
+--  data/
+
+source-repository head
+  type:     git
+  location: https://github.com/sboosali/spiros
+
+
+library
+ hs-source-dirs:      sources
+ default-language:    Haskell2010
+ ghc-options:         -Wall
+
+ exposed-modules:
+  Prelude.Spiros
+  Digit
+
+ other-modules:
+  Spiros.Utilities
+
+ build-depends:
+    base                 >= 4.6   && <5.0
+
+  -- , basic-prelude
+  -- --  extra symbols
+  -- , base-prelude
+  -- --  all of base, modulo conflicting symbols
+  -- , mtl-prelude
+  -- --  Reexports of most definitions from \"mtl\" and \"transformers\".
+  , safe
+
+  , mtl
+  , transformers
+
+  , stm
+  , vinyl
+  -- ??
+
+  -- , async
+  -- , parallel
+
+  , deepseq
+  , hashable
+  , semigroups
+
+  , text
+  , bytestring
+
+  , unordered-containers
+  , containers
+  , vector               
+
+  , time
+  , process
+  , directory
+  -- , shake
+  -- , optparse-applicative >= 0.10  && <0.13
+  -- , optparse-generic     >= 1.1.0 && <1.2
+
+  , split
+  , wl-pprint-text
+  , data-default-class
+
+  -- , interpolatedstring-perl6
+  -- needs haskell-src-exts
diff --git a/stack.yaml b/stack.yaml
new file mode 100644
--- /dev/null
+++ b/stack.yaml
@@ -0,0 +1,13 @@
+resolver: lts-8.12
+compiler: ghc-8.0.2
+
+nix:
+   # enable: true  
+   # on NixOS (and/or Linux/OSX), you global stack.yaml can enable `nix`. otherwise, it's disabled. 
+  pure: true
+  packages: []
+
+packages:
+- .
+
+extra-deps: []
