-- infinite sequences

struct Infseq a = head_ :: a
		  tail_ :: Infseq a

x `app` s = struct head_ = x
		   tail_ = s

blink     = struct head_ = 0
	           tail_ = 1 `app` blink


-- streams

struct Stream a = ht :: Maybe (a,Stream a)

nats n     = struct ht = Just (n,nats (n+1))
			       
s @@ s'    = struct ht = case s.ht of Just (x,t) -> Just (x,t@@s')
				      _ -> s'.ht

zips s s'  = struct ht = case s.ht of Just (x,t) -> Just (x,zips s' t)
				      _ -> s'.ht

maps f s   = struct ht = do (x,t) <- s.ht
			    Just (f x,maps f t)

exists g s = case s.ht of Just (x,t) -> g x || exists g t
		 	  _ -> False

nth 0 s    = do (x,t) <- s.ht
	        Just x
nth n s    = do (_,t) <- s.ht
	        x <- nth (n-1) t
	        Just x


-- bags

struct Bag a = card :: a -> Int

mtBag       = struct card = const 0

single x    = struct card y = if y == x then 1 else 0

b `union` c = struct card x = b.card x + c.card x

