ABList (empty) → 0.0.1
raw patch · 5 files changed
+238/−0 lines, 5 filesdep +HUnitdep +QuickCheckdep +basesetup-changed
Dependencies added: HUnit, QuickCheck, base, linear, newtype, test-framework, test-framework-hunit, test-framework-quickcheck2
Files
- ABList.cabal +39/−0
- Setup.hs +2/−0
- src/Data/AbList.hs +109/−0
- src/Data/AbneList.hs +70/−0
- test/Tests.hs +18/−0
+ ABList.cabal view
@@ -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
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/Data/AbList.hs view
@@ -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+
+ src/Data/AbneList.hs view
@@ -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
+ test/Tests.hs view
@@ -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+ ]