------------------------------------------------------------------------------ --The files in this directory are based on the programs described in: -- -- A Modular fully-lazy lambda lifter in Haskell -- Simon L. Peyton Jones and David Lester -- Software -- Practice and Experience -- Vol 21(5), pp.479-506 -- MAY 1991 -- --See the Readme file for more details. ------------------------------------------------------------------------------ -- Utilities: -- The following general purpose function is defined in the above paper: mapAccuml :: (b -> a -> (b,c)) -> b -> [a] -> (b,[c]) mapAccuml f b [] = (b,[]) mapAccuml f b (a:as) = (b'',c:cs) where (b',c) = f b a (b'',cs) = mapAccuml f b' as -- All subsequent definitions are my own implementations of functions -- specified only by type signatures and informal descriptions in the -- paper -- so blame me for any errors or misinterpretations! -- Sets: sets are implemented as ordered lists with no repetitions, as -- suggested by the use of (Ord) in the given signatures. -- Just for a change, we'll write these definitions out as -- iterations... data Set a = Set [a] setDifference :: Ord a => Set a -> Set a -> Set a setDifference (Set xs) (Set ys) = Set (differ xs ys) where differ (x:xs) (y:ys) | x==y = differ xs ys | x Set a -> Set a -> Set a setIntersect (Set xs) (Set ys) = Set (intersect xs ys) where intersect (x:xs) (y:ys) | x==y = x : intersect xs ys | x Set a -> Set a -> Set a setUnion (Set xs) (Set ys) = Set (union xs ys) where union (x:xs) (y:ys) | x==y = x : union xs ys | x [Set a] -> Set a setUnionList = foldr setUnion setEmpty setToList :: Set a -> [a] setToList (Set xs) = xs setFromList :: Ord a => [a] -> Set a setFromList = Set . sort . nub setSingleton :: a -> Set a setSingleton a = Set [a] setEmpty :: Set a setEmpty = Set [] -- Bags: the given interface doesn't impose any constraint on the types -- that can be held in bags, so it doesn't seem that there is much -- to do other than make a bag type out of lists... for the benefits -- of type checking, I'll make a separate Bag data type constructor, -- although a synonym would have been acceptable... data Bag a = Bag [a] bagUnion :: Bag a -> Bag a -> Bag a bagUnion (Bag xs) (Bag ys) = Bag (xs++ys) bagInsert :: a -> Bag a -> Bag a bagInsert x (Bag xs) = Bag (x:xs) bagToList :: Bag a -> [a] bagToList (Bag bag) = bag bagFromList :: [a] -> Bag a bagFromList = Bag bagSingleton :: a -> Bag a bagSingleton x = Bag [x] bagEmpty :: Bag a bagEmpty = Bag [] -- Association lists: type Assn a b = [(a,b)] assLookup :: Eq a => Assn a b -> a -> b assLookup ps a = head [ b | (a',b) <- ps, a==a' ] -- Name supply: type NameSupply = Int initialNameSupply :: NameSupply initialNameSupply = 0 newName :: NameSupply -> String -> (NameSupply,String) newName ns prefix = (ns+1, prefix ++ show ns) -- That's it!!!