import Data.List (sortBy,sort)
-- A student is presented by his name, student id and a list of courses the student is taking
-- for example= [("zjz",000,[001,002]),("zjz2",001,[001,002])]
type Student = (String, Int, [Int])
type DB = [Student]
-- no duplicates,return ture
noDuplicates :: DB -> Bool
noDuplicates xs =
and (map (\x -> [x] == (filter(\x' ->x == x')xs))
xs)
-- map遍历输入变量的所有值
-- filter检查变量某值是否正确
-- and所有名字都不重复返回正确
-- task 0
-- to ensure the database is consistent
-- which means: 1.no multiple entries of students
-- 2.no multiple entries of courses per student
-- 3.no multiple entries of student's id
valid :: DB -> Bool
valid db = valid1 db && valid2 db && valid3
valid1 db =
let students = map(\(s,_,_) -> s)db
in noDuplicates students
valid2 db =
and (map((\(_,_,courses)-> noDuplicates courses) db)
valid3 db =
let studentsid = map(\(_,id,_) -> id)db
in noDuplicates studentsid
-- task1
-- for a given database and students' id,
-- looking for the list of courses this particular student taken
myfun1 :: DB ->Int -> [Int]
myfun1 [] _ = []
myfun1 db stdid = head [cors |(_,id,cors)<- db, id== stdid]
-- task2
-- for a given database and a course
-- find all students who are taking this course
myfun2 ::DB -> Int -> [String]
myfun2 [] _ = []
myfun2 ((name,_,cours):left) course
| elem course cours = name:(myfun2 rest course)
-- elem函数 判断某元素是否在list 在Ture,否False
| otherwise = myfun2 rest course
--task3
-- for a given database, sort it in non-decreasing order
-- according to the name of students
myfun_sort :: DB -> DB
myfun_sort db = sortBy(\(s1,_,_) -> \(s2,_,_) ->
if s1 == s2 then EQ
else if s1 < s2 then LT
else GT)db
-- task4
-- for two given databases, merge them to obtain one (consistenet) database
myfun_merge :: DB -> DB -> DB
myfun_merge db1 db2 = merge' (myfunsort db1) (myfunsort db2)
where
merge' [] db = db
merge' db [] = db
merge' ((n1,id1,c1):db1) ((n2,id2,c2):db2)
| n1 == n2 = (n1,id1,myfun3(c1 ++ c2)) : merge' db1 db2
| n1 < n2 = (n1,id1,c1) : merge' db1 ((n2,id2,c2):db2)
| n1 > n2 = (n2,id2,c2) : merge' ((n1,id1,c1):db1) db2
myfun3 xs = myfun3' [] xs
myfun3' co_number [] = co_number
myfun3' co_number (x:xs)
| elem x co_number = myfun3' co_number xs
| otherwise = fun3' (x:co_number) xs