diff --git a/ABList.cabal b/ABList.cabal
new file mode 100644
--- /dev/null
+++ b/ABList.cabal
@@ -0,0 +1,39 @@
+Name:               ABList
+Version:            0.0.1
+Author:             Dylan Just <dylan@techtangents.com>
+License:            BSD3
+Copyright:          Dylan Just, Travis Cardwell
+Maintainer:         Dylan Just
+Category:           Control
+Synopsis:           An alternating list of two types
+Description:        An alternating list of two types
+Cabal-version:      >= 1.10
+Build-Type:         Simple
+
+
+Library
+  default-language: Haskell2010
+  Build-Depends:    base < 5 && >= 3,
+                    linear,
+                    newtype
+
+  GHC-Options:      -Wall
+                    -fno-warn-type-defaults
+                    -fno-warn-name-shadowing
+
+  Exposed-Modules:  Data.AbList
+                    Data.AbneList
+  hs-source-dirs:   src
+
+
+test-suite the-tests
+  default-language:  Haskell2010
+  type:              exitcode-stdio-1.0
+  hs-source-dirs:    test, src
+  main-is:           Tests.hs
+  build-depends:     base,
+                     HUnit,
+                     QuickCheck,
+                     test-framework,
+                     test-framework-hunit,
+                     test-framework-quickcheck2
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/src/Data/AbList.hs b/src/Data/AbList.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/AbList.hs
@@ -0,0 +1,109 @@
+module Data.AbList where
+
+import Prelude
+
+infixr 5 :/
+data AbList a b = AbNil | a :/ AbList b a
+  deriving (Eq, Ord, Show)
+
+abSingle :: a -> AbList a b
+abSingle a = a :/ AbNil
+
+abShallowFold :: t -> (a -> AbList b a -> t) -> (AbList a b) -> t
+abShallowFold t _ AbNil = t
+abShallowFold _ t (a :/ ba) = t a ba
+
+abToListEither :: AbList a b -> [Either a b]
+abToListEither AbNil = []
+abToListEither (a :/ AbNil) = [Left a]
+abToListEither (a :/ b :/ abz) = (Left a) : (Right b) : abToListEither abz
+
+abFromListEither :: [Either a b] -> Maybe (AbList a b)
+abFromListEither [] = Just AbNil
+abFromListEither (Left a : []) = Just $ a :/ AbNil
+abFromListEither (Left a : Right b : xs) = fmap (\t -> a :/ b :/ t) (abFromListEither xs)
+abFromListEither _ = Nothing
+
+abHead :: AbList a b -> Maybe a
+abHead = abShallowFold Nothing $ const . Just
+
+abTail :: AbList a b -> Maybe (AbList b a)
+abTail = abShallowFold Nothing $ const Just
+
+abInit :: AbList a b -> Maybe (AbList a b)
+abInit AbNil = Nothing
+abInit (a :/ as) = Just $ q a as
+  where
+    q :: a -> AbList b a -> AbList a b
+    q _ AbNil = AbNil
+    q x (y :/ zs) = x :/ q y zs
+
+aaToList :: AbList a a -> [a]
+aaToList AbNil = []
+aaToList (a :/ as) = a : (aaToList as)
+
+aaMap :: (a -> b) -> AbList a a -> AbList b b
+aaMap _ AbNil = AbNil
+aaMap f (a :/ as) = f a :/ (aaMap f as)
+
+aaFromList :: [a] -> AbList a a
+aaFromList = foldr (:/) AbNil
+
+abFoldr :: (Either a b -> t -> t) -> t -> (AbList a b) -> t
+abFoldr f = abFoldr' (f . Left) (f . Right)
+
+abFoldr' :: (a -> t -> t) -> (b -> t -> t) -> t -> (AbList a b) -> t
+abFoldr' _ _ t AbNil = t
+abFoldr' f _ t (a :/ AbNil) = f a t
+abFoldr' f g t (a :/ b :/ cs) = f a (g b (abFoldr' f g t cs))
+
+abFoldl :: (t -> Either a b -> t) -> t -> (AbList a b) -> t
+abFoldl f = abFoldl' ((. Left) . f) ((. Right) . f)
+
+abFoldl' :: (t -> a -> t) -> (t -> b -> t) -> t -> (AbList a b) -> t
+abFoldl' _ _ t AbNil = t
+abFoldl' f _ t (a :/ AbNil) = f t a
+abFoldl' f g t (a :/ b :/ cs) = abFoldl' f g (f (g t b) a) cs
+
+abZip :: [a] -> [b] -> AbList a b
+abZip [] _ = AbNil
+abZip (a:_) [] = a :/ AbNil
+abZip (a:as) (b:bs) = a :/ b :/ (abZip as bs)
+
+abFromPairs :: [(a, b)] -> AbList a b
+abFromPairs = foldr (\(a, b) cs -> a :/ b :/ cs) AbNil
+
+abToPairs :: AbList a b -> [(a, b)]
+abToPairs AbNil = []
+abToPairs (_ :/ AbNil) = []
+abToPairs (a :/ b :/ cs) = (a,b) : abToPairs cs
+
+abMap :: (a -> a') -> (b -> b') -> AbList a b -> AbList a' b'
+abMap _ _ AbNil = AbNil
+abMap fa _ (a :/ AbNil) = fa a :/ AbNil
+abMap fa fb (a :/ b :/ cs) = fa a :/ fb b :/ (abMap fa fb cs)
+
+abMerge :: (a -> t) -> (b -> t) -> AbList a b -> [t]
+abMerge f g = aaToList . (abMap f g)
+
+-- thanks to Travis Cardwell ("tcard")
+abReverse :: AbList a b -> Either (AbList a b) (AbList b a)
+abReverse = goAB AbNil
+ where
+   goAB :: AbList b a -> AbList a b -> Either (AbList a b) (AbList b a)
+   goAB acc AbNil = Right acc
+   goAB acc (x :/ xs) = goBA (x :/ acc) xs
+   goBA :: AbList a b -> AbList b a -> Either (AbList a b) (AbList b a)
+   goBA acc AbNil = Left acc
+   goBA acc (x :/ xs) = goAB (x :/ acc) xs
+
+abMapLefts :: (a -> a') -> AbList a b -> AbList a' b
+abMapLefts = flip abMap id
+
+abMapRights :: (b -> b') -> AbList a b -> AbList a b'
+abMapRights = abMap id
+
+-- right-biased functor
+instance Functor (AbList a) where
+  fmap = abMapRights
+
diff --git a/src/Data/AbneList.hs b/src/Data/AbneList.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/AbneList.hs
@@ -0,0 +1,70 @@
+module Data.AbneList where
+
+import Data.AbList
+
+infixr 5 ://
+data AbneList a b = a :// AbList b a
+  deriving (Eq, Ord, Show)
+
+abneHead :: AbneList a b -> a
+abneHead (a :// _) = a
+
+abneTail :: AbneList a b -> AbList b a
+abneTail (_ :// as) = as
+
+--test
+abneShallowFold :: (a -> AbList b a -> t) -> AbneList a b -> t
+abneShallowFold f (a :// as) = f a as
+
+toAbList :: AbneList a b -> AbList a b
+toAbList = abneShallowFold (:/)
+
+fromAbList :: AbList a b -> Maybe (AbneList a b)
+fromAbList = abShallowFold Nothing $ (Just .) . (://)
+
+-- TODO: convert to a NonEmpty (Either a b) <-- which NonEmpty lib, though?
+abneToListEither :: AbneList a b -> [Either a b]
+abneToListEither = abToListEither . toAbList
+
+abneFromListEither :: [Either a b] -> Maybe (AbneList a b)
+abneFromListEither =
+  (fromAbList =<<) . abFromListEither
+
+abneInit :: AbneList a b -> AbList a b
+abneInit = abneShallowFold q
+  where
+    q :: a -> AbList b a -> AbList a b
+    q _ AbNil = AbNil
+    q x (y :/ zs) = x :/ q y zs
+
+aaneToList :: AbneList a a -> [a]
+aaneToList = aaToList . toAbList
+
+aaneMap :: (a -> b) -> AbneList a a -> AbneList b b
+aaneMap f (a :// as) = f a :// aaMap f as
+
+aaneFromList :: [a] -> Maybe (AbneList a a)
+aaneFromList = fromAbList . aaFromList
+
+abneFoldr :: (Either a b -> t -> t) -> t -> (AbneList a b) -> t
+abneFoldr f t = abFoldr f t . toAbList
+
+abneFoldr' :: (a -> t -> t) -> (b -> t -> t) -> t -> (AbneList a b) -> t
+abneFoldr' f g t = abFoldr' f g t . toAbList
+
+abneFoldl :: (t -> Either a b -> t) -> t -> (AbneList a b) -> t
+abneFoldl f t = abFoldl f t . toAbList
+
+abneFoldl' :: (t -> a -> t) -> (t -> b -> t) -> t -> (AbneList a b) -> t
+abneFoldl' f g t = abFoldl' f g t . toAbList
+
+abneZip :: [a] -> [b] -> Maybe (AbneList a b)
+abneZip = (fromAbList .) . abZip
+
+abneFromPairs :: [(a, b)] -> Maybe (AbneList a b)
+abneFromPairs = fromAbList . abFromPairs
+
+-- reduce
+-- reverse
+-- map
+-- functor
diff --git a/test/Tests.hs b/test/Tests.hs
new file mode 100644
--- /dev/null
+++ b/test/Tests.hs
@@ -0,0 +1,18 @@
+module Main where
+
+import Test.Framework
+import Test.Framework.Providers.QuickCheck2
+import Test.Framework.Providers.HUnit
+import Test.QuickCheck
+
+import qualified AbListTests (tests)
+import qualified AbneListTests (tests)
+
+main :: IO ()
+main = defaultMain [tests]
+
+tests =
+  testGroup "the"
+  [ AbListTests.tests
+  , AbneListTests.tests
+  ]
