Skip to content

Latest commit

 

History

History
347 lines (321 loc) · 6.59 KB

ch09.adoc

File metadata and controls

347 lines (321 loc) · 6.59 KB

9 Lists

9.5 Using ranges to construct lists

Exercise

The trick here was to use fromEnum and toEnum to get Int and avoid using Ord constrain in the signature. Got this insight from reading the Enum class source code - http://hackage.haskell.org/package/base-4.8.2.0/docs/src/GHC.Enum.html#Enum

link:ch09_9.5_0.hs[role=include]

Writing my own enumFromTo for the following types is kind a of arbitrary since I did myEnumFromTo.

link:ch09_9.5_1.hs[role=include]

9.6 Extracting portions of lists

Intermission: Exercises

  1. make words function using dropWhile and takeWhile

    1. first attempt

      link:ch09_9.6_0_1.hs[role=include]
    2. no need for lambdas

      link:ch09_9.6_0_2.hs[role=include]
    3. we can turn it into case

      link:ch09_9.6_0_3.hs[role=include]
    4. simplyfy more

      link:ch09_9.6_0_4.hs[role=include]
    5. this one is very close to the version in Prelude, using break

      link:ch09_9.6_0_5.hs[role=include]
    6. and version from the book in the 9.14 Answers chapter. Pretty neat, did not think about matching the space as a pattern.

      link:ch09_9.6_0_6.hs[role=include]
  2. break String on newlines

    link:ch09_9.6_1.hs[role=include]
  3. parametrized myWords and myLines

    link:ch09_9.6_2.hs[role=include]

9.7 List comprehensions

Adding predicates

mySqr = [x^2 | x <- [1..10]]
-- result
[1,4,9,16,25,36,49,64,81,100]

[x | x <- mySqr, rem x 2 == 0]
-- result
[4,16,36,64,100]

[(x, y) | x <- mySqr, y <- mySqr, x < 50, y > 50]
-- result
[(1,64),(1,81),(1,100),(4,64),(4,81),(4,100),(9,64),(9,81),(9,100),(16,64),(16,81),(16,100),(25,64),(25,81),(25,100),(36,64),(36,81),(36,100),(49,64),(49,81),(49,100)]

take 5 [(x, y) | x <- mySqr, y <- mySqr, x < 50, y > 50]
-- result
[(1,64),(1,81),(1,100),(4,64),(4,81)]

List comprehensions with Strings

Prelude> let mySqr = [x^2 | x <- [1..5]]
Prelude> let myCube = [y^3 | y <- [1..5]]
  1. tuples of mySqr and myCube

    [(x, y) | x <- mySqr, y <- myCube]
    -- [(1,1),(1,8),(1,27),(1,64),(1,125),(4,1),(4,8),(4,27),(4,64),(4,125),(9,1),(9,8),(9,27),(9,64),(9,125),(16,1),(16,8),(16,27),(16,64),(16,125),(25,1),(25,8),(25,27),(25,64),(25,125)]
  2. x and y from previous point that are less than 50

    [(x, y) | x <- mySqr, y <- myCube, x < 50, y < 50]
    -- [(1,1),(1,8),(1,27),(4,1),(4,8),(4,27),(9,1),(9,8),(9,27),(16,1),(16,8),(16,27),(25,1),(25,8),(25,27)]
  3. number of tuples from previuos point

    length [(x, y) | x <- mySqr, y <- myCube, x < 50, y < 50]
    -- 15

9.8 Spines and non-strict evaluation

Intermission: Exercises

Will it blow up?

  1. yes, it gets evaluated to undefined because of x^y

    [x^y | x <- [1..5], y <- [2, undefined]]
  2. no, only first element of list get evaluated

    take 1 $ [x^y | x <- [1..5], y <- [2, undefined]]
  3. yes, sum breaks on undefined

    sum [1, undefined, 3]
  4. no, length ignores values

    length [1, 2, undefined]
  5. yes, undefined is part of spine

    length $ [1, 2, 3] ++ undefined
  6. no, evaluates to second list element

    take 1 $ filter even [1, 2, 3, undefined]
  7. yes, take 1 forces filter to evaluate until undefined

    take 1 $ filter even [1, 3, undefined]
  8. no, only first element evaluated

    take 1 $ filter odd [1, 3, undefined]
  9. no, only first two elemnts evaluated

    take 2 $ filter odd [1, 3, undefined]
  10. yes, trird element is undefined

    take 3 $ filter odd [1, 3, undefined]

Is it in normal form?

Warning
not sure
  1. WHHNF and NF, all evaluated [1, 2, 3, 4, 5]

  2. WHNF because of _ in 1 : 2 : 3 : 4 : _

  3. neither, not data constructor enumFromTo 1 10

  4. neither, not data constructor length [1, 2, 3, 4, 5]

  5. neither, not data constructor sum (enumFromTo 1 10)

  6. neither, not data constructor ['a'..'m'] ++ ['n'..'z']

  7. WHFN, not all evaluated (_, 'b')

9.9 Transforming lists of values

  1. will return bottom, take 1 evaluates undefined

    take 1 $ map (+1) [undefined, 2, 3]
  2. returns 2

    take 1 $ map (+1) [1, undefined, 3]
  3. bottom, second element is undefined and is evaluated by take 2

    take 2 $ map (+1) [1, undefined, 3]
  4. function transforms String into a list of Bool depending if character is vovel, type in code

    itIsMystery :: String -> [Bool]
    itIsMystery xs = map (\x -> elem x "aeiou") xs
  5. results

    1. map (^2) [1..10] evaluates to [1,4,9,16,25,36,49,64,81,100]

    2. map minimum [[1..10], [10..20], [20..30]] evaluates to [1,10,20]

    3. map sum [[1..5], [1..5], [1..5]] evaluates to [15,15,15]

  6. rewrite

    link:ch09_9.9_0.hs[role=include]

9.10 Filtering lists of values

  1. filter (\x → (rem x 3) == 0) [1..30]

  2. (length . filter (\ x → (rem x 3) == 0)) [1 .. 30]

  3. myFilter = filter (\x → not (elem x ["the", "a", "an"])) . words

9.11 Zipping lists

  1. zip implementation, using a little trick that any empty list falls through to the all-catch pattern. Could be written on more lines explicitly matching the empty lists.

    link:ch09_9.11_0.hs[role=include]
  2. zipWith implementation

    link:ch09_9.11_1.hs[role=include]

9.12 Chapter Exercises

Data.Char

  1. isUpper :: Char → Bool, toUpper :: Char → Char

  2. let fUp = filter (\x → isUpper x)

  3. capitalize first letter

    link:ch09_9.12_0.hs[role=include]
  4. capitalize all letters

    link:ch09_9.12_1.hs[role=include]
  5. capitalize and return first letter using head

    link:ch09_9.12_2.hs[role=include]
  6. previous function as composed and then pointfree

    link:ch09_9.12_3.hs[role=include]

Ciphers

link:ch09_9.12_cipher.hs[role=include]

Writing your own standard functions

  1. myOr

    link:ch09_9.12_4.hs[role=include]
  2. myAny

    link:ch09_9.12_5.hs[role=include]
  3. myElem

    link:ch09_9.12_6.hs[role=include]
  4. myReverse

    link:ch09_9.12_7.hs[role=include]
  5. squish

    link:ch09_9.12_8.hs[role=include]
  6. squishMap

    link:ch09_9.12_9.hs[role=include]
  7. squishAgain

    link:ch09_9.12_10.hs[role=include]
  8. myMaximumBy

    link:ch09_9.12_11.hs[role=include]
  9. myMinimumBy, myMaximum, myMinimum

    link:ch09_9.12_12.hs[role=include]