home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 2
/
DATAFILE_PDCD2.iso
/
utilities
/
_gofer
/
!Gofer
/
archives
/
Demos
/
Modular
/
Utility
< prev
Wrap
Text File
|
1993-02-12
|
4KB
|
114 lines
------------------------------------------------------------------------------
--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<y = x : differ xs (y:ys)
| y<x = differ (x:xs) ys
differ xs _ = xs
setIntersect :: Ord a => 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<y = intersect xs (y:ys)
| y<x = intersect (x:xs) ys
intersect _ _ = []
setUnion :: Ord a => 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<y = x : union xs (y:ys)
| y<x = y : union (x:xs) ys
union xs ys = xs ++ ys
setUnionList :: Ord a => [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!!!