public
Last active

  • Download Gist
library2.hs
Haskell
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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
module Library
(Author,
Book,
AuthorIndex,
BookIndex,
Catalogued,
Catalog,
addAuthor,
addBook,
associate,
authors,
books,
catalogued
) where
 
import qualified Data.Map as Map
 
data Author = Author String deriving (Show, Eq, Ord)
data Book = Book String deriving (Show, Eq, Ord)
type AuthorIndex = Map.Map Author [Book]
type BookIndex = Map.Map Book [Author]
 
data Catalog =
Catalog {
authorIndex :: AuthorIndex,
bookIndex :: BookIndex
} deriving (Show)
 
 
-- class for determining if a book or author is
-- in the catalog
class Catalogued a where
catalogued :: a -> Catalog -> Bool
 
 
-- ********************************
-- API (exported) methods
-- ********************************
addAuthor :: Author -> Catalog -> Catalog
addAuthor a c@(Catalog as bs) =
c { authorIndex = insertUnlessPresent a [] as }
 
addBook :: Book -> Catalog -> Catalog
addBook b c@(Catalog as bs) =
c { bookIndex = insertUnlessPresent b [] bs }
 
-- associate an author "a" with a book "b"
-- this will update both the book and author
-- indexes in a given catalog
associate :: Author -> Book -> Catalog -> Catalog
associate a b (Catalog as bs) = Catalog as' bs'
where
as' = Map.alter (addValue b) a as
bs' = Map.alter (addValue a) b bs
addValue x Nothing = Just [x]
addValue x (Just ys) = Just (x:ys)
 
-- Return all the authors for a book as listed in a catalog
authors :: Book -> Catalog -> Maybe [Author]
authors b c = Map.lookup b (bookIndex c)
 
-- return all the books written by an author as listed in a catalog
books :: Author -> Catalog -> Maybe [Book]
books a c = Map.lookup a (authorIndex c)
 
-- returns True if an author or book is in
-- the given catalog
instance Catalogued Author where
catalogued a c = a `Map.member` (authorIndex c)
 
instance Catalogued Book where
catalogued b c = b `Map.member` (bookIndex c)
 
 
-- ********************************
-- private (unexported) methods
-- ********************************
 
insertUnlessPresent k v m
| k `Map.member` m = m
| otherwise = Map.insert k v m

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.