diff --git a/code/FUP-hw.csv b/code/FUP-hw.csv new file mode 100644 index 0000000..e6bd15c --- /dev/null +++ b/code/FUP-hw.csv @@ -0,0 +1,85 @@ +Elle Smith,,15,,40,,,, +Alina Contreras,10,5,13,10,11,10,13,8 +Angel Rojas,10,8,15,27,12,24,12,7 +Malik Ortiz,2,20,1,24,11,17,13,9 +Laila Malone,10,5.5,15,7,11,4,13,2 +Carsen Li,10,6,15,1,12,5,13,8 +Elliott Ramsey,10,0,15,10,11,10,6,10 +Kylan Mckinney,10,3,15,5,12,3,13,3 +Sariah Norris,9,20,14,8,4,15,3,20 +Judah Snow,2,10,15,25,11,25,6,25 +Paloma Norris,10,8,15,15,11,15,13,20 +Sierra Gaines,10,4,15,5,12,6,13,3 +Giada Mason,9,7,15,12,9,7,11,11 +Harper Booker,10,3,13,6,6,3,10,4 +Jamari Serrano,10,4,15,5,12,3,10,3 +Talon Dixon,,,,,,,, +Deon Wise,10,6,15,10,6,2,6,4 +Jazmyn Cox,9,16,15,16,11,8,10,16 +Jermaine Kramer,10,0,15,2,11,1,6,1 +Cristina Ewing,10,20,15,20,11,20,13,8 +Savion Burnett,10,6,15,27,3,2,4,6 +Clark Gillespie,10,3,15,5,11,5,13,3 +Jamir Cooke,5,14,,,0,50,, +Darwin Dennis,,,,,,,, +Arturo Gilmore,10,8,15,12,11,4,10,8 +Leland Smith,10,1,3,1,10,1,13,1 +Jadyn Vaughn,,,,,,,, +Kamari Bauer,10,8,15,20,12,10,13,6 +Javier Gill,3,10,,,,,, +Guillermo Ellison,10,12,12,25,8,11,4,8 +Jamie Conner,10,6,15,8,12,5,11,4 +Riley Bradshaw,10,5,15,12,11,8,13,2 +Tia Montoya,10,6,15,13,11,10,13,6 +Marley Olson,10,8,15,13,11,14,13,7 +Laci Martin,10,5,15,10,5,5,13,10 +Colten Black,10,0,15,20,10,8,4,0 +Calvin Bell,10,9,15,23,9,9,13,7 +Jennifer Villegas,10,20,14,15,9,5,4,0.5 +Fiona Hudson,,,,,,,, +Brianna Skinner,10,6,13,24,11,8,13,10 +Valentin Russo,10,8,15,10,11,12,13,8 +Parker Andrews,10,7,15,5,12,4,13,1 +Caiden Humphrey,8,17,15,25,6,21,4,5 +Reagan Barry,10,20,15,20,3,1,6,10 +Beau Henson,9,0,7,3,8,6,10,10 +Preston Green,9,24,14,72,7,36,10,48 +Kaitlin Berg,7,30,,,3,16,, +Brett Mahoney,9,8,15,9,12,3,4,2 +Zackary Hopkins,10,0,15,3,11,3,13,3 +Madelynn Moses,10,0,15,4,6,3,6,10 +Payton Burke,10,8,15,10,12,8,13,6 +Craig Poole,10,3,15,10,12,6,13,3 +Alejandro Ward,10,6,14,20,9,10,4,1 +Adriel Gay,,,,,,,, +Aaron Burke,10,4,15,6.5,12,9,13,3 +Rayne Mckinney,10,0,15,1,11,2,4,1 +Jovani Schmitt,10,3,15,8,12,8,13,4 +Stephanie Fisher,10,10,6,25,4,13,, +Kamden Klein,,0,,,,,, +Ryleigh Barber,9,8,15,2,12,4,4,1 +Bridget Dunn,2,14,1,8,12,9,13,7 +Miah Andrade,9,0,,,,,, +Gauge Conley,10,6.4,15,8.2,11,4.5,13,6.1 +Melanie Winters,10,0,3,4,9,2,13,2 +Noe Chapman,10,4,15,6,12,8,13,3 +Elisabeth Costa,10,4,15,7,12,3,13,5 +Hailie Eaton,10,6,15,4,12,5,13,3.5 +Joselyn Gates,10,20,15,45,12,20,4,1 +Valentin Ashley,10,8,15,10,7,9,4,7 +Rowan Colon,10,6,,,5,6,, +Ann Sandoval,10,10,15,15,10,10,6,6 +Jorden Mcconnell,10,5,15,12,7,5,4,1 +Selina Larson,10,16,13,24,10,5,7,4 +Nikhil Young,10,6,14,19,9,4,6,1 +Carolyn Blake,9,11,15,16,3,1,11,7 +Gunner Montoya,10,8,15,20,11,20,13,8 +Elisha Church,10,8,14,20,4,3,11,5 +Ivy Rosales,6,0,1,140,6,50,13,30 +Sabrina Matthews,10,2.5,12,4,12,5,13,3 +Rory Carter,10,0,15,3,12,4,4,1 +Aidan Hernandez,10,20,13,50,3,1,6,6 +Titus Mckay,1,4,1,22,10,11,13,6 +Elisha Rogers,10,10,15,10,12,8,13,6 +Jaliyah Avila,10,10,15,20,11,15,13,10 +Ryder Owen,,,,,,,, diff --git a/code/lecture13.hs b/code/lecture13.hs new file mode 100644 index 0000000..d161c31 --- /dev/null +++ b/code/lecture13.hs @@ -0,0 +1,163 @@ +import Data.Monoid +import Data.Foldable ( foldl', foldl ) +import qualified Data.Set as Set +import qualified Data.Map as Map +import Data.Char ( toLower ) +import Text.Read ( readMaybe ) +import Data.Maybe ( fromMaybe, isJust ) + +m2 :: (a -> m1) -> (a -> m2) -> (a -> (m1,m2)) +m2 f g = \x -> (f x, g x) + +m3 :: (a -> m1) -> (a -> m2) -> (a -> m3) -> (a -> (m1,m2,m3)) +m3 f g h = \x -> (f x, g x, h x) + +data Min a = Min a | MinEmpty deriving (Show) + +data Max a = Max a | MaxEmpty deriving (Show) + +newtype Count = Count Int deriving (Show) + +instance (Ord a) => Semigroup (Min a) where + MinEmpty <> m = m + m <> MinEmpty = m + (Min a) <> (Min b) = Min (min a b) + +instance (Ord a) => Monoid (Min a) where + mempty = MinEmpty + +instance (Ord a) => Semigroup (Max a) where + MaxEmpty <> m = m + m <> MaxEmpty = m + (Max a) <> (Max b) = Max (max a b) + +instance (Ord a) => Monoid (Max a) where + mempty = MaxEmpty + +instance Semigroup Count where + (Count n1) <> (Count n2) = Count (n1+n2) + +instance Monoid Count where + mempty = Count 0 + +count :: a -> Count +count _ = Count 1 + +-- Set is a monoid under union +--Set.fromList [1..5] <> Set.fromList [3..10] + +-- Map is a monoid under union as well +--Map.fromList [(1,"a")] <> Map.fromList [(1,"b")] + +-- Another Monoid instance for Map +newtype MMap k v = MMap (Map.Map k v) + +fromList :: Ord k => [(k,v)] -> MMap k v +fromList xs = MMap (Map.fromList xs) + +singleton :: k -> v -> MMap k v +singleton k v = MMap (Map.singleton k v) + +showMap :: (Show k, Show v) => Map.Map k v -> String +showMap m = "Map (\n" ++ ls ++ ")" where + ls = concat $ map line (Map.toList m) + line (k,v) = " " ++ show k ++ " : " ++ show v ++"\n" + +instance (Show k, Show v) => Show (MMap k v) where + show (MMap m) = "M" ++ showMap m + +instance (Ord k, Monoid v) => Semigroup (MMap k v) where + (MMap m1) <> (MMap m2) = MMap (Map.unionWith mappend m1 m2) + +instance (Ord k, Monoid v) => Monoid (MMap k v) where + mempty = MMap Map.empty + + +--MMap (Map.fromList [(1,"a")]) <> MMap (Map.fromList [(1,"b")]) + +-- Foldable +myFoldMap :: Monoid m => (a -> m) -> [a] -> m +myFoldMap f = mconcat . map f + +data Tree a = Leaf a | Node (Tree a) (Tree a) deriving Show + +instance Foldable Tree where + foldMap f (Leaf x) = f x + foldMap f (Node l r) = foldMap f l <> foldMap f r + +tree :: Tree Int +tree = Node (Leaf 7) (Node (Leaf 2) (Leaf 3)) + +-- Folding over Set +--foldMap Sum $ Set.fromList [1..10] + +-- Folding with the Set monoid +--foldMap Set.singleton [1,2,4,2,1,5] + +-- Folding over Map +-- foldMap id $ Map.fromList [(1,"a"),(2,"b")] + +-- Folding with Map monoids +--foldMap (\x -> Map.singleton x (x^2)) [1..10] +--foldMap (\x -> MMap (Map.singleton x (count x))) [1,2,3,3,2,4,5,5,5] + +-- Mean of a list +mean :: Fractional a => [a] -> a +mean xs = s / fromIntegral l where + (Sum s,Count l) = foldMap (m2 Sum count) xs + +-- filtering in folding +mfilter :: Monoid m => (a -> Bool) -> (a -> m) -> (a -> m) +mfilter pred f x = if pred x then f x else mempty + +--foldMap (m2 Sum (mfilter (<=20) Sum)) [5,10,20,45.4,35,1,3.4] +--foldMap (m2 (mfilter (>0) Sum) (mfilter (<0) Sum)) [3,-2,5,-8] + +-- GroupBy operation on Map +groupBy :: (Ord k, Monoid m) => (a -> k) -> (a -> m) -> (a -> MMap k m) +groupBy keyf valuef a = singleton (keyf a) (valuef a) + + +ws = words $ map toLower "Size matters not. Look at me. Judge me by my size, do you? Hmm? Hmm. And well you should not. For my ally is the Force, and a powerful ally it is. Life creates it, makes it grow. Its energy surrounds us and binds us. Luminous beings are we, not this crude matter. You must feel the Force around you; here, between you, me, the tree, the rock, everywhere, yes. Even between the land and the ship." + +stats word = (count word, Min $ length word, Max $ length word) +-- foldMap (groupBy head (m3 count (Min . length) (Max . length))) ws +-- 𝝺> foldMap (groupBy head stats) ws + +-- Example CSV +type Record a b = [(a,b)] + +splitOn :: Char -> String -> [String] +splitOn delimiter = foldr f [""] + where f c l@(x:xs) | c == delimiter = "":l + | otherwise = (c:x):xs + +parseRecord :: String -> Record String Float +parseRecord str = [ (k,fromMaybe 0 v) | (k,v) <- pairs, isJust v ] + where keys = ["hw1", "time1", "hw2", "time2", "hw3", "time3", "hw4", "time4"] + vals = map readMaybe $ tail (splitOn ',' str) + pairs = zip keys vals + +parseCSV :: [String] -> Record String Float +parseCSV lines = mconcat $ map parseRecord lines + +-- getStats :: Record String Float -> Record String (Float, Float) +getStats rec = avgs + where (MMap stats) = foldMap (groupBy fst (m3 count (Sum . snd) (Max . snd))) rec + avgs = fmap (\(Count n, Sum s, Max m) -> (s/fromIntegral n, m)) stats + +-- Lazy vs strict fold +lazyFold :: Integer +lazyFold = foldl (+) 0 [1..10^7] + +strictFold :: Integer +strictFold = foldl' (+) 0 [1..10^7] + +main :: IO () +main = do lns <- lines <$> readFile "FUP-hw.csv" + let rec = parseCSV lns + print $ foldMap (groupBy fst (m3 count (Sum . snd) (Max . snd))) rec + putStrLn $ showMap $ getStats rec + + + diff --git a/lectures/index.md b/lectures/index.md index 30047c4..4cb51ed 100644 --- a/lectures/index.md +++ b/lectures/index.md @@ -95,6 +95,15 @@ We discuss some more examples of type classes, most importantly `Functor`s. [`State.hs`](https://github.com/aicenter/FUP/blob/main/lectures/State.hs). [`StateIO.hs`](https://github.com/aicenter/FUP/blob/main/lectures/StateIO.hs). +## Lecture 13: Monoids & Foldables + +Lecture notes coming soon! + +[Slides](https://github.com/aicenter/FUP/blob/main/lectures/lecture13.pdf). +[Log](https://github.com/aicenter/FUP/blob/main/code/lecture13.hs). +[Dataset](https://github.com/aicenter/FUP/blob/main/code/FUP-hw.csv). + + ## Old recorded lectures diff --git a/lectures/lecture11.md b/lectures/lecture11.md index bb8725c..9577c74 100644 --- a/lectures/lecture11.md +++ b/lectures/lecture11.md @@ -284,7 +284,7 @@ instance Applicative Parser where Just (True, "c") 𝝺> parse ((/=) <$> item <*> item) "aac" -Just (True, "c") +Just (False, "c") ``` diff --git a/lectures/lecture13.pdf b/lectures/lecture13.pdf new file mode 100644 index 0000000..cc776bf Binary files /dev/null and b/lectures/lecture13.pdf differ