Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lecture 13 #29

Merged
merged 2 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions code/FUP-hw.csv
Original file line number Diff line number Diff line change
@@ -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,,,,,,,,
163 changes: 163 additions & 0 deletions code/lecture13.hs
Original file line number Diff line number Diff line change
@@ -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



9 changes: 9 additions & 0 deletions lectures/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion lectures/lecture11.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ instance Applicative Parser where
Just (True, "c")

𝝺> parse ((/=) <$> item <*> item) "aac"
Just (True, "c")
Just (False, "c")
```


Expand Down
Binary file added lectures/lecture13.pdf
Binary file not shown.