haskell - Reflexive Closure -


i have been working on question reflexive closure:

the reflexive closure of relation r smallest relation bigger r reflexive. in other words, r whatever pairs added make r reflexive. write function (reflclosure) takes list of pairs (standing r) , returns list of pairs reflexive closure of r. not need worry order in pairs appear in return value.

i came solution seems quite sloppy , lack neatness.

-- question 2: functions , relations  reflclosure :: (eq a) => [(a,a)] -> [(a,a)] reflclosure (x:xs) = nub ( (x:xs) ++ [ (x,x) | x <- (heads (x:xs)) ++ (tails  (x:xs)) ])  nub :: eq => [a] -> [a] nub = nubby (==)  nubby :: (a -> -> bool) -> [a] -> [a] nubby eq [] = [] nubby eq (x:xs) = x : nubby eq (filter (\y -> not (eq x y)) xs)  heads :: (eq a) => [(a,a)] -> [a] heads list = nub [x | (x, _) <- list]  tails :: (eq a) => [(a,a)] -> [a] tails list = nub [x | (_,x) <- list]  exists :: (eq a) => (a,a) -> [(a,a)] -> bool exists x xs = length (filter (==x) xs) > 0   -- test set q2 {- functions should have following behaviour: reflclosure [(1,2),(3,2)] = [(1,2),(3,2),(1,1),(2,2),(3,3)] reflclosure [(1,1),(3,5)] = [(1,1),(3,5),(3,3),(5,5)]  not worry order in pairs appear in list -} 

is there easier way this? explanation incredibly useful learn well.

a nicer way write heads , tails following:

heads :: (eq a) => [(a,a)] -> [a] heads = nub . map fst  tails :: (eq a) => [(a,a)] -> [a] tails = nub . map snd 

it's point-free, plus uses more "functional" map rather list comprehension.

however, fact need both means there's nicer way:

(heads (x:xs), tails (x:xs)) = (\(a,b) -> (nub a) (nub b)) $ unzip (x:xs) 

getting fsts , snds equivalent unzip.

also, can simplify signature of exists:

exists :: (eq a) => -> [a] -> bool exists x xs = length (filter (==x) xs) > 0 

since nothing depends on input being list of pairs.

data.list defines nubby, i'm not sure why you've defined there.

it's not clear why you've defined reflclosure match on (x:xs), because care (apparently) list non-empty. perhaps this:

reflclosure :: (eq a) => [(a,a)] -> [(a,a)] reflclosure [] = [] reflclosure xs =    let (as,bs) = unzip xs   in nub $ xs ++ [ (x,x) | x <- (nub as) ++ (nub bs) ] 

Comments