You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

63 lines
1.9 KiB

module DBProcess where
import Data.Time
data DatabaseItem = DbString String
| DbNumber Integer
| DbDate UTCTime
deriving (Eq, Ord, Show)
theDatabase :: [DatabaseItem]
theDatabase =
[ DbDate (UTCTime
(fromGregorian 1911 5 1)
(secondsToDiffTime 34123))
, DbNumber 9001
, DbString "Hello, world!"
, DbDate (UTCTime
(fromGregorian 1921 5 1)
(secondsToDiffTime 34123))
]
-- 1
filterDbDate :: [DatabaseItem] -> [UTCTime]
filterDbDate = foldr f []
where f (DbDate u) xs = u : xs
f _ xs = xs
-- 2
filterDbNumber :: [DatabaseItem] -> [Integer]
filterDbNumber = foldr f []
where f (DbNumber i) xs = i : xs
f _ xs = xs
-- 3
mostRecent :: [DatabaseItem] -> UTCTime
mostRecent = maximum . filterDbDate
-- with folds, this is more difficult, because it's not easy to find the
-- right zero value. Ideally it would be the smallest UTCTime possible.
mostRecent' :: [DatabaseItem] -> UTCTime
mostRecent' = foldr f z
where f (DbDate u1) u2 = max u1 u2
f _ u = u
z = UTCTime d 0
d = (toEnum (minBound :: Int) :: Day)
-- The problem here is that even this day is not the smallest possible,
-- because you can simply do `pred d` which gives a smaller day. So the
-- original solution is superior.
-- 4
sumDb :: [DatabaseItem] -> Integer
sumDb = sum . filterDbNumber
-- with folds
sumDb' :: [DatabaseItem] -> Integer
sumDb' = foldr f 0
where f (DbNumber i1) i2 = i1 + i2
f _ i2 = i2
-- 5
avgDb :: [DatabaseItem] -> Double
avgDb [] = undefined -- 0/0
avgDb xs = (fromIntegral . sumDb $ xs ) / (fromIntegral . length $ xs)