module Text.LParse.TokenStream where
import Data.Either
import Data.Maybe
import Data.Traversable
import Prelude hiding (filter,zip,zipWith,drop)
class (Functor t, Foldable t) => TokenStream t where
top :: t a -> a
rest :: t a -> t a
nil :: t a
cons :: a -> t a -> t a
instance TokenStream [] where
top = head
rest = tail
nil = []
cons = (:)
instance TokenStream Maybe where
top = fromJust
rest = const Nothing
nil = Nothing
cons a _ = Just a
instance TokenStream (Either a) where
top = head . rights . return
rest x = if isLeft x then x else nil
nil = Left undefined
cons a _ = Right a
drop :: (TokenStream s) => Int -> s a -> s a
drop 0 x = x
drop n x = rest $ drop (n-1) x
zip :: (TokenStream s) => s a -> s b -> s (a,b)
zip = zipWith (,)
zipWith :: (TokenStream s) => (a -> b -> c) -> s a -> s b -> s c
zipWith f l r | null l || null r = nil
| otherwise = f (top l) (top r) `cons` zipWith f (rest l) (rest r)
filter :: (TokenStream s) => (a -> Bool) -> s a -> s a
filter c x | null x = nil
| c (top x) = top x `cons` filter c (rest x)
| otherwise = filter c (rest x)