module Data.FixedList (
Cons(..)
, Nil(..)
, FixedList
, Append (..)
, reverse
, length
, last
, init
, unit
, subLists
, fromFoldable
, fromFoldable'
, FixedList0, FixedList1, FixedList2, FixedList3, FixedList4
, FixedList5, FixedList6, FixedList7, FixedList8, FixedList9
, FixedList10, FixedList11, FixedList12, FixedList13, FixedList14
, FixedList15, FixedList16, FixedList17, FixedList18, FixedList19
, FixedList20, FixedList21, FixedList22, FixedList23, FixedList24
, FixedList25, FixedList26, FixedList27, FixedList28, FixedList29
, FixedList30, FixedList31, FixedList32
) where
import Control.Applicative
import Control.Monad hiding (sequence)
import Data.Foldable
import Data.Traversable
import Data.Monoid
import Data.Maybe
import qualified Data.List
import Prelude hiding (head, tail, foldr, sum, sequence, reverse, length, last, init)
data FixedList f =>
Cons f a = (:.) {
head :: a,
tail :: (f a)
} deriving (Eq, Ord)
data Nil a = Nil
deriving (Eq, Ord)
infixr 5 :.
instance (FixedList f, Show a) => Show (Cons f a) where
show x = "|" ++ show (toList x) ++ "|"
instance Show (Nil a) where
show Nil = "|[]|"
class (Applicative f, Traversable f, Monad f) => FixedList f
instance FixedList f => FixedList (Cons f)
instance FixedList Nil
class Append f g h | f g -> h, f h -> g where
append :: f a -> g a -> h a
instance (FixedList f, FixedList c, Append f b c) => Append (Cons f) b (Cons c) where
append (x :. xs) ys = x :. (xs `append` ys)
instance Append Nil a a where
append Nil ys = ys
reverse :: FixedList t => t a -> t a
reverse xs = fromFoldable' $ Data.List.reverse $ toList xs
length :: Foldable t => t a -> Int
length xs = Data.List.length $ toList xs
last :: Foldable t => t a -> a
last xs = Data.List.last $ toList xs
init :: FixedList f => Cons f a -> f a
init xs = fromFoldable' $ Data.List.init $ toList xs
unit :: a -> Cons Nil a
unit a = a :. Nil
subLists :: FixedList f => Cons f a -> Cons f (f a)
subLists xs = fromFoldable' $ fmap fromFoldable' $ subLists' $ toList xs
where
subLists' a = zipWith (++) (Data.List.inits a) ( Data.List.tail $ Data.List.tails a)
fromFoldable :: (Foldable f, Applicative g, Traversable g) => f a -> Maybe (g a)
fromFoldable t = sequenceA $ snd $ mapAccumL f (toList t) (pure ())
where
f [] _ = ([], Nothing)
f (x:xs) _ = (xs, Just x)
fromFoldable' :: (Foldable f, Applicative g, Traversable g) => f a -> g a
fromFoldable' a = fromJust $ fromFoldable a
instance FixedList f => Functor (Cons f) where
fmap f (a :. b) = f a :. fmap f b
instance FixedList f => Foldable (Cons f) where
foldMap f (a :. b) = f a `mappend` foldMap f b
instance FixedList f => Traversable (Cons f) where
traverse f (a :. b) = (:.) <$> f a <*> traverse f b
instance FixedList f => Monad (Cons f) where
return x = x :. return x
(a :. b) >>= k = head (k a) :. (b >>= (tail . k))
instance FixedList f => Applicative (Cons f) where
pure = return
(<*>) = ap
instance Functor Nil where
fmap _ Nil = Nil
instance Foldable Nil where
foldMap _ Nil = mempty
instance Traversable Nil where
traverse _ Nil = pure Nil
instance Monad Nil where
return _ = Nil
Nil >>= _ = Nil
instance Applicative Nil where
pure = return
(<*>) = ap
instance (Num a, FixedList f, Eq (f a), Show (f a)) => Num (Cons f a) where
a + b = pure (+) <*> a <*> b
a b = pure () <*> a <*> b
a * b = pure (*) <*> a <*> b
negate a = pure negate <*> a
abs a = pure abs <*> a
signum = fmap signum
fromInteger = pure . fromInteger
instance (Fractional a, FixedList f, Eq (f a), Show (f a)) => Fractional (Cons f a) where
a / b = pure (/) <*> a <*> b
recip a = pure 1 / a
fromRational = pure . fromRational
type FixedList0 = Nil
type FixedList1 = Cons FixedList0
type FixedList2 = Cons FixedList1
type FixedList3 = Cons FixedList2
type FixedList4 = Cons FixedList3
type FixedList5 = Cons FixedList4
type FixedList6 = Cons FixedList5
type FixedList7 = Cons FixedList6
type FixedList8 = Cons FixedList7
type FixedList9 = Cons FixedList8
type FixedList10 = Cons FixedList9
type FixedList11 = Cons FixedList10
type FixedList12 = Cons FixedList11
type FixedList13 = Cons FixedList12
type FixedList14 = Cons FixedList13
type FixedList15 = Cons FixedList14
type FixedList16 = Cons FixedList15
type FixedList17 = Cons FixedList16
type FixedList18 = Cons FixedList17
type FixedList19 = Cons FixedList18
type FixedList20 = Cons FixedList19
type FixedList21 = Cons FixedList20
type FixedList22 = Cons FixedList21
type FixedList23 = Cons FixedList22
type FixedList24 = Cons FixedList23
type FixedList25 = Cons FixedList24
type FixedList26 = Cons FixedList25
type FixedList27 = Cons FixedList26
type FixedList28 = Cons FixedList27
type FixedList29 = Cons FixedList28
type FixedList30 = Cons FixedList29
type FixedList31 = Cons FixedList30
type FixedList32 = Cons FixedList31