compdata-0.5: src/Data/Comp/Zippable.hs
--------------------------------------------------------------------------------
-- |
-- Module : Data.Comp.Zippable
-- Copyright : (c) 2011 Patrick Bahr
-- License : BSD3
-- Maintainer : Patrick Bahr <paba@diku.dk>
-- Stability : experimental
-- Portability : non-portable (GHC Extensions)
--
--
--------------------------------------------------------------------------------
module Data.Comp.Zippable
( Zippable (..)
, Numbered(..)
, unNumbered
, number
, number'
, Stream(..)
, (<:>)) where
-- import Data.Stream (Stream(..), (<:>))
data Stream a = Cons a (Stream a) deriving (Eq, Ord)
infixr 5 <:>
-- | The @ \<:\> @ operator is an infix version of the 'Cons'
-- constructor.
(<:>) :: a -> Stream a -> Stream a
(<:>) = Cons
-- | Instances of this class provide a generalisation of the zip
-- function on the list functor.
class Functor f => Zippable f where
fzip :: Stream a -> f b -> f (a,b)
fzip = fzipWith (\ x y -> (x,y))
fzipWith :: (a -> b -> c) -> Stream a -> f b -> f c
fzipWith f s l = fmap (uncurry f) (fzip s l)
-- | This type is used for applying a DDTAs.
newtype Numbered a = Numbered (Int, a)
unNumbered :: Numbered a -> a
unNumbered (Numbered (_, x)) = x
instance Eq (Numbered a) where
Numbered (i,_) == Numbered (j,_) = i == j
instance Ord (Numbered a) where
compare (Numbered (i,_)) (Numbered (j,_)) = i `compare` j
number :: Zippable f => f a -> f (Numbered a)
number t = fzipWith (curry Numbered) (nums 0) t
where nums x = x `Cons` nums (x+1)
number' :: Zippable f => f a -> f (Int, a)
number' t = fzipWith num (nums 0) t
where nums x = x <:> nums (x+1)
num n a = (n,a)
instance Zippable [] where
fzip (Cons x xs) (y:ys) = (x,y) : fzip xs ys
fzip _ [] = []
fzipWith f (Cons x xs) (y:ys) = f x y : fzipWith f xs ys
fzipWith _ _ [] = []