Skip to content

Add stack to project for deps management #2

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

Merged
merged 22 commits into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
feat: backup
  • Loading branch information
OlaoluwaM committed Apr 30, 2024
commit f4eda57022f8452efa3a54c64d896468cb17a075
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
"haskell": false,
"markdown": false
},
"cSpell.words": ["Ceaser"]
"cSpell.words": ["Ceaser", "hspec"]
}
4 changes: 1 addition & 3 deletions app/Main.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
module Main (main) where

import Lib

main :: IO ()
main = someFunc
main = putStrLn "Hi"
25 changes: 23 additions & 2 deletions haskell-from-first-principles-exercies.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,41 @@ source-repository head

library
exposed-modules:
Ch14.Addition
other-modules:
Ch10.Playground
Ch11.Cipher
Ch11.HuttonsRazor
Ch11.Phone
Ch11.PhoneAlt
Ch9.Cipher
Ch11.Playground
Ch12.Playground
Ch13.Person
Ch13.Playground
Ch14.Morse
Ch14.Playground
Ch8.Playground
Ch9.Cipher
Ch9.Playground
Ch9.StdFunc
Lib
Paths_haskell_from_first_principles_exercies
autogen-modules:
Paths_haskell_from_first_principles_exercies
hs-source-dirs:
src
default-extensions:
ImportQualifiedPost
LambdaCase
ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints
build-depends:
base >=4.7 && <5
PyF
, QuickCheck
, base >=4.7 && <5
, containers
, hspec
, random
, time
default-language: Haskell2010

executable haskell-from-first-principles-exercies-exe
Expand Down
17 changes: 8 additions & 9 deletions package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,15 @@ ghc-options:

library:
source-dirs: src

dependencies:
- random
- time
- PyF
- containers
- hspec
- QuickCheck
exposed-modules:
- Ch11.Cipher
- Ch11.Phone
- Ch11.PhoneAlt
- Ch9.Cipher
- Ch12.Playground
- Lib

other-modules: []
- Ch14.Addition

executables:
haskell-from-first-principles-exercies-exe:
Expand Down
125 changes: 60 additions & 65 deletions src/ch10/exercises.lhs → src/Ch10/Exercises.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
Chapter 10 Exercises
========================
# Chapter 10 Exercises

Exercise: Understanding Folds
=============================
## Exercise: Understanding Folds

1. $foldr (*) 1 [1..5]$ Will return the same result as which of the following?
1. `foldr (*) 1 [1..5]` Will return the same result as which of the following?

a) flip (*) 1 [1..5]
b) foldl (flip (*)) 1 [1..5]
c) foldl (*) 1 [1..5]
a) `flip (*) 1 [1..5]`
b) `foldl (flip (*)) 1 [1..5]`
c) `foldl (*) 1 [1..5]`

Answer: c & b.

2. Write out the evaluation steps for: $foldl (flip (*)) 1 [1..3]$
2. Write out the evaluation steps for: `foldl (flip (*)) 1 [1..3]`

filp (*) is equivalent to (*) because multiplication is commutative
`filp (*)` is equivalent to `(*)` because multiplication is commutative

```haskell
foldl (*) 1 [1, 2, 3]
foldl (*) (1 * 1) [2, 3]
foldl (*) (1 *1) [2, 3]
foldl (*) ((1 * 1) * 2) [3]
foldl (*) (((1 * 1) * 2) * 3) []
(((1 * 1) * 2) * 3)
((1 * 2) * 3)
(2 * 3)
foldl (*) (((1* 1) *2)* 3) []
(((1 *1)* 2) *3)
((1* 2) *3)
(2* 3)
6
```

3. One difference between foldr and foldl is:
3. One difference between `foldr` and `foldl` is:

a) foldr, but not foldl, traverses the spine of a list from right
a) `foldr`, but not `foldl`, traverses the spine of a list from right
to left.
b) foldr, but not foldl, always forces the rest of the fold.
c) foldr, but not foldl, associates to the right.
d) foldr, but not foldl, is recursive.
b) `foldr`, but not `foldl`, always forces the rest of the fold.
c) `foldr`, but not `foldl`, associates to the right.
d) `foldr`, but not `foldl`, is recursive.

Answer: c.

Expand All @@ -47,65 +47,61 @@ Answer: a.
5.The following are simple folds very similar to what you’ve already seen, but each has at least one error. Please fix and test
them in your REPL:

> foldr (++) ["woot", "WOOT", "woot"]
> foldr (++) "" ["woot", "WOOT", "woot"]
```haskell
foldr (++) ["woot", "WOOT", "woot"]
foldr (++) "" ["woot", "WOOT", "woot"]

> foldr max "fear is the little death"
> foldr max 'a' "fear is the little death"
foldr max "fear is the little death"
foldr max 'a' "fear is the little death"

> foldr and True [False, True]
> foldr (&&) True [False, True]
foldr and True [False, True]
foldr (&&) True [False, True]

> foldr (||) True [False, True]
> foldr (||) False [False, True]
foldr (||) True [False, True]
foldr (||) False [False, True]

> foldl ((++) . show) "" [1..5]
> foldr ((++) . show) "" [1..5]
foldl ((++) . show) "" [1..5]
foldr ((++) . show) "" [1..5]

> foldr const 'a' [1..5]
> foldr (flip const) 'a' [1..5]
> foldl const 'a' [1..5]
foldr const 'a' [1..5]
foldr (flip const) 'a' [1..5]
foldl const 'a' [1..5]

> foldr const 0 "tacos"
> foldr (flip const) 0 "tacos"
> foldl const 0 "tacos"
foldr const 0 "tacos"
foldr (flip const) 0 "tacos"
foldl const 0 "tacos"

> foldl (flip const) 0 "burritos"
> foldl const 0 "burritos"
> foldr (flip const) 0 "burritos"
foldl (flip const) 0 "burritos"
foldl const 0 "burritos"
foldr (flip const) 0 "burritos"

> foldl (flip const) 'z' [1..5]
> foldl const 'z' [1..5]
> foldr (flip const) 'z' [1..5]
foldl (flip const) 'z' [1..5]
foldl const 'z' [1..5]
foldr (flip const) 'z' [1..5]
```

Exercise : Database Processing
==============================
## Exercise : Database Processing

$$
\begin{code}
```haskell
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))]

\end{code}
$$
```

1. Write a function that filters for $DbDate$ values and returns a list of the $UTCTime$ values inside them:

$$
\begin{code}
```haskell
filterDbDate :: [DatabaseItem] -> [UTCTime]
filterDbDate = foldr getDates []
where
getDates (DbDate date) acc = date : acc
getDates _ acc = acc
\end{code}
$$
```

2. Write a function that filters for $DbNumber$ values and returns a list of the Integer values inside them:
1. Write a function that filters for $DbNumber$ values and returns a list of the Integer values inside them:

$$
\begin{code}
Expand Down Expand Up @@ -144,7 +140,6 @@ avgDb dbIs = let dbNums = filterDbNumber dbIs in fromIntegral (fromInteger (sum
\end{code}
$$


Scan Exercises
==============

Expand Down Expand Up @@ -257,19 +252,19 @@ Rewriting functions using folds
10. $myMaximumBy$ takes a comparison function and a list and returns the greatest element of the list based on the last value that the comparison returns GT for:

> myMaximumBy :: (a -> a -> Ordering) -> [a] -> a
> myMaximumBy _ [x] = x
> myMaximumBy _[x] = x
> myMaximumBy compareFn (x : xs) = case compareFn x tailMax of
> GT -> x
> _ -> tailMax
> where
> tailMax = myMaximumBy compareFn xs
> GT -> x
>_ -> tailMax
> where
> tailMax = myMaximumBy compareFn xs

11. $myMinimumBy$ takes a comparison function and a list and returns the least element of the list based on the last value that the comparison returns LT for:

> myMinimumBy :: (a -> a -> Ordering) -> [a] -> a
> myMinimumBy _ [x] = x
> myMinimumBy _[x] = x
> myMinimumBy compareFn (x : xs) = case compareFn x tailMin of
> LT -> x
> _ -> tailMin
> where
> tailMin = myMinimumBy compareFn xs
> LT -> x
>_ -> tailMin
> where
> tailMin = myMinimumBy compareFn xs
6 changes: 3 additions & 3 deletions src/ch10/Playground.hs → src/Ch10/Playground.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module Playground where
module Ch10.Playground where

import Data.Foldable (Foldable (foldl'))
import Data.Time
Expand Down Expand Up @@ -135,5 +135,5 @@ myMinimumBy compareFn (x : xs) = case compareFn x tailMin of
squishMap'' :: (Foldable t) => (a1 -> [a2]) -> t a1 -> [a2]
squishMap'' f = foldr (f >>> (++)) []

squishMap''' :: (Foldable t) => (a1 -> [a2]) -> t a1 -> [a2]
squishMap''' f = foldl ((++) . f) []
-- squishMap''' :: (Foldable t) => (a1 -> [a2]) -> t a1 -> [a2]
-- squishMap''' f = foldl ((++) . f) []
2 changes: 1 addition & 1 deletion src/Ch11/Cipher.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module Ch11.Cipher where
module Ch11.Cipher (vigenereCipher, CaesarCipher.cipherMsg) where

import Ch9.Cipher qualified as CaesarCipher

Expand Down
File renamed without changes.
File renamed without changes.
82 changes: 82 additions & 0 deletions src/Ch14/Addition.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
module Ch14.Addition where

import Ch8.Playground (dividedBy, recursiveMult)
import Test.Hspec

import Test.QuickCheck

test :: IO ()
test = hspec $ do
describe "Division" $ do
it "15 divided by 3 is 5" $ do
dividedBy 15 3 `shouldBe` Just (5, 0)
it "22 divided by 5 is 4 remainder 2" $ do
dividedBy 22 5 `shouldBe` Just (4, 2)
describe "Addition" $ do
it "should ensure that x + 1 is always greater than x" $ do
property $ \x -> (x + 1) > (x :: Integer)

test2 :: IO ()
test2 = hspec $ do
describe "Recursive Multiplication" $ do
it "should check that 5 can be recursively multiplied with 5 to give 25" $ do
recursiveMult 5 5 `shouldBe` 25
it "should check that 9 can be recursively multiplied with 15 to give 135" $ do
recursiveMult 9 15 `shouldBe` 135

trivialInt :: Gen Int
trivialInt = return 1

oneThroughThree :: Gen Int
oneThroughThree = elements [1, 2, 2, 2, 2, 3]

genBool :: Gen Bool
genBool = choose (False, True)

genBool' :: Gen Bool
genBool' = elements [False, True]

genOrdering :: Gen Ordering
genOrdering = elements [LT, EQ, GT]

genChar :: Gen Char
genChar = elements ['a' .. 'z']

genTuple :: (Arbitrary a, Arbitrary b) => Gen (a, b)
genTuple = do
a <- arbitrary
b <- arbitrary
return (a, b)

genThreeple :: (Arbitrary a, Arbitrary b, Arbitrary c) => Gen (a, b, c)
genThreeple = do
(a, b) <- genTuple
c <- arbitrary
return (a, b, c)

genEither :: (Arbitrary a, Arbitrary b) => Gen (Either a b)
genEither = do
(a, b) <- genTuple
elements [Left a, Right b]

genMaybe :: (Arbitrary a) => Gen (Maybe a)
genMaybe = do
a <- arbitrary
elements [Just a, Nothing]

genMaybe' :: (Arbitrary a) => Gen (Maybe a)
genMaybe' = do
a <- arbitrary
frequency [(1, return Nothing), (3, return $ Just a)]

propAdditionGreater :: Int -> Bool
propAdditionGreater x = x + 1 > x

propAdditionGreaterUntrue :: Int -> Bool
propAdditionGreaterUntrue x = x + 0 > x

runQc :: IO ()
runQc = quickCheck propAdditionGreater

runQcFail :: IO ()
runQcFail = quickCheck propAdditionGreaterUntrue
Loading