forked from sjsyrek/haskell-study-startup
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathset.hs
51 lines (40 loc) · 1.79 KB
/
set.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
-- Written as part of the "Coding Dojo: Containers" by Simon Fromme, 2018
module Set where
import Data.List (intercalate, sort)
import Data.Set (Set, empty, fromList, intersection, singleton,
toList, union, unions, (\\))
type Database = (String, Set String)
type Class = (Set String, Set String)
parseFileContent :: String -> [Database]
parseFileContent = map parseLine . sort . lines
parseLine :: String -> Database
parseLine s = let xs = words s in (head xs, (fromList . sort . tail) xs)
classToStr :: Class -> String
classToStr (names, attributes) = "CL " ++ nameStr ++ ": " ++ attrStr where
nameStr = intercalate "_" (toList names)
attrStr = intercalate ", " (toList attributes)
databaseToStr :: Database -> String
databaseToStr (name, columns) = "TB " ++ name ++ ": " ++ columnStr where
columnStr = intercalate ", " (toList columns)
classHierarchy :: [Database] -> [Class]
classHierarchy dbs = go leafClasses 0 [] where
leafClasses = map (\(s, elems) -> (singleton s, elems)) dbs
go cls n akk
| n == length leafClasses = akk
| otherwise = go (unique cls') (n + 1) (akk' ++ akk) where
akk' = if n == length leafClasses - 1
then cls
else [(e, n \\ others) | (e, n) <- cls,
let others = unions [n' | (e', n') <- cls, e' /= e]]
cls' = [(union n1 n2, intersection e1 e2) | (n1, e1) <- cls, (n2, e2) <- cls, n1 < n2]
unique = toList . fromList
compileTable :: String -> IO ()
compileTable filename = do
input <- readFile filename
putStrLn $ "Test: " ++ filename
let dbs = parseFileContent input
out f = putStrLn . intercalate "\n" . map f in do
out databaseToStr dbs
out classToStr (classHierarchy dbs)
main :: IO ()
main = compileTable "/tmp/in"