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
						
					
					
				
			
		
		
	
	
							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) |