packages feed

lhc-0.6.20081127: src/Util/Relation.hs

-- | extend Data.Set with relation operations

module Util.Relation(module Util.Relation, module Set) where

import Data.Set as Set hiding(map)
import qualified Data.Set as Set (map)

type Rel a b = Set (a,b)


domain :: (Ord a,Ord b) => Rel a b -> Set a
domain r = Set.map fst r

range :: (Ord a,Ord b) => Rel a b -> Set b
range r = Set.map snd r

flipRelation :: (Ord a, Ord b) => Rel a b -> Rel b a
flipRelation = Set.map (\ (x,y) -> (y,x))

restrictDomain :: (Ord a, Ord b) => (a -> Bool) -> Rel a b -> Rel a b
restrictDomain f r = Set.filter (f . fst) r

restrictRange :: (Ord a, Ord b) => (b -> Bool) -> Rel a b -> Rel a b
restrictRange f r = Set.filter (f . snd) r


mapDomain :: (Ord a, Ord b, Ord c) => (a -> c) -> Rel a b -> Rel c b
mapDomain f r = Set.map (\ (x,y) -> (f x,y)) r

mapRange :: (Ord a, Ord b, Ord c) => (b -> c) -> Rel a b -> Rel a c
mapRange f r = Set.map (\ (x,y) -> (x,f y)) r

partitionDomain f r = Set.partition (f . fst) r

partitionRange f r = Set.partition (f . snd) r

applyRelation :: (Ord a, Ord b) => Rel a b -> a -> [b]
applyRelation r a = Prelude.map snd (toList $ restrictDomain (== a) r)

toRelationList :: (Ord a, Ord b) => Rel a b -> [(a,[b])]
toRelationList rel = [ (x, applyRelation rel x) | x <- toList (domain rel)]