Part 19

Quiz and Cheatsheet

Why can’t we map Nothing?

  1. Because Nothing doesn’t take arguments
  2. Because Nothing returns nothing
  3. Because Nothing is a constructor.

If we define data Boing = Frick String Boing (Int -> Bool), what is the type of Frick?

  1. Boing
  2. String -> Boing -> Int -> Bool -> Boing
  3. String -> Boing -> (Int -> Bool) -> Boing

If we define data ThreeLists a b c = ThreeLists [a] [b] [c], what is the type of the constructor ThreeLists?

  1. [a] -> [b] -> [c] -> ThreeLists
  2. a -> b -> c -> ThreeLists a b c
  3. [a] -> [b] -> [c] -> ThreeLists a b c
  4. [a] -> [b] -> [c] -> ThreeLists [a] [b] [c]

If we define data TwoLists a b = TwoList {aList :: [a], bList :: [b]}, what is the type of the function aList?

  1. aList is not a function, it is a field
  2. TwoLists a b -> [a]
  3. [a] -> TwoLists a b
  4. [a]

Cheatsheet

Thanks again to our TA Daan Wichmann for the following cheatsheet. Note that while this cheatsheet can help you to prepare for the exam, it is non-exhaustive, and your own responsibility that you go through all material.

import qualified Data.Map as Map  -- Qualified import Data.Map as Map (because of overlap with Prelude)
import Data.Array

myTuple :: (String,String)
myTuple = ("Hello","World!")

-- fst :: (a, b) -> a
-- snd :: (a, b) -> b

-- zip :: [a] -> [b] -> [(a, b)]
-- unzip :: [(a, b)] -> ([a], [b])

-- elements that satisfy and don't satisfy a predicate
-- partition :: (a -> Bool) -> [a] -> ([a], [a])

-- swap :: (a,b) -> (b,a)

-- sum all numbers that are paired with True
sumIf :: [(Bool,Int)] -> Int
sumIf [] = 0
sumIf ((True,x):xs) = x + sumIf xs
sumIf ((False,_):xs) = sumIf xs

summed = sumIf [(True,1),(False,10),(True,100)]
-- Output: 101

-- FOLDING
-- foldr :: (a -> b -> b) -> b -> [a] -> b
-- foldr f y []     = y
-- foldr f y (x:xs) = f x (foldr f y xs)

-- nub :: Eq a => [a] -> [a] (removes duplicates from lists)

-- Ord type class is used for ordering operations (>=, <=, >, <, min, max)

-- Num type class contains integer arithmatic (also shows up in in types of integer literals)
-- (+) :: Num a => a -> a -> a
-- (-) :: Num a => a -> a -> a
-- (*) :: Num a => a -> a -> a
-- negate :: Num a => a -> a                  0-x
-- abs :: Num a => a -> a                     absolute value
-- signum :: Num a => a -> a                  -1 for negative values, 0 for 0, +1 for positive values
-- fromInteger :: Num a => Integer -> a

-- Integral is the type class that represents all whole numberts (Int, Integer)
-- All types that belong to Integral also belong to Num
-- div :: Integral a => a -> a -> a
-- mod :: Integral a => a -> a -> a

-- Fractional is the class for types that have division (all types of Fractional also belong to Num)
-- (/) :: Fractional a => a -> a -> a

-- Floating contains some additional operators that only make sense for floating point numbers.
-- All types that belong to Floating also belong to Factional (and so, also to Num)
-- sqrt :: Floating a => a -> a
-- sin :: Floating a => a -> a

-- Read and Show
-- show :: Show a => a -> String
-- read :: Read a => String -> a

readInt = read "127" :: Int -- We tell the compiler to read to an Int (could also be a float for example)

-- Foldable: represents types you can fold over

-- MAPS

-- Create a Map from a list of key-value pairs
-- Map.fromList :: Ord k => [(k, a)] -> Map.Map k a

-- Insert a value into a map. Overrides any previous value with the same key.
-- Returns a new map. Does not mutate the given map.
-- Map.insert :: Ord k => k -> a -> Map.Map k a -> Map.Map k a

-- Get a value from a map using a key. Returns Nothing if the key was not present in the map.
-- Map.lookup :: Ord k => k -> Map.Map k a -> Maybe a

-- An empty map
-- Map.empty :: Map.Map k a

-- Maps are implemented as ordered binary search trees (thats why we need the Ord type constraint)

withdraw :: String -> Int -> Map.Map String Int -> Map.Map String Int
withdraw account amount bank =
    case Map.lookup account bank of
        Nothing  -> bank                                   -- account not found, no change
        Just sum -> Map.insert account (sum-amount) bank   -- set new balance

-- Equivalent
withdrawAdjust :: String -> Int -> Map.Map String Int -> Map.Map String Int
withdrawAdjust account amount bank = Map.adjust (\x -> x-amount) account bank

-- ARRAY

-- Type signature of array
-- array :: Ix i => (i, i) -> [(i, e)] -> Array i e

myArray :: Array Int String
myArray = array (7,11) [(7,"seven"), (8,"eight"), (9,"nine"), (10,"ten"), (11,"ELEVEN")]

-- listArray :: Ix i => (i, i) -> [e] -> Array i e

-- Equivalent to myArray
myListArray :: Array Int String
myListArray = listArray (7,11) ["seven", "eight", "nine", "ten", "ELEVEN"]

-- Array lookup
-- (!) :: Ix i => Array i e -> i -> e
-- Array update
-- (//) :: Ix i => Array i e -> [(i, e)] -> Array i e

-- arrays and maps are also Foldable (so you can use length and foldr)
You have reached the end of this section!

You can check your current points from the blue blob in the bottom-right corner of the page.