Skip to content

Commit b95c375

Browse files
committed
Refactored the Applicative chapter using stack
0 parents  commit b95c375

27 files changed

+685
-0
lines changed

.gitignore

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Haskell
2+
dist
3+
dist-*
4+
cabal-dev
5+
*.o
6+
*.hi
7+
*.chi
8+
*.chs.h
9+
*.dyn_o
10+
*.dyn_hi
11+
.hpc
12+
.hsenv
13+
.cabal-sandbox/
14+
cabal.sandbox.config
15+
*.prof
16+
*.aux
17+
*.hp
18+
*.eventlog
19+
.stack-work/
20+
cabal.project.local
21+
cabal.project.local~
22+
.HTF/
23+
.ghc.environment.*
24+
25+
# Custom
26+
haskell-programming-from-first-principles.cabal
27+
*~

ChangeLog.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Changelog for haskell-programming-from-first-principles
2+
3+
## Unreleased changes

LICENSE

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
Copyright BoeingX (c) 2018
2+
3+
All rights reserved.
4+
5+
Redistribution and use in source and binary forms, with or without
6+
modification, are permitted provided that the following conditions are met:
7+
8+
* Redistributions of source code must retain the above copyright
9+
notice, this list of conditions and the following disclaimer.
10+
11+
* Redistributions in binary form must reproduce the above
12+
copyright notice, this list of conditions and the following
13+
disclaimer in the documentation and/or other materials provided
14+
with the distribution.
15+
16+
* Neither the name of BoeingX nor the names of other
17+
contributors may be used to endorse or promote products derived
18+
from this software without specific prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

README.md

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Haskell Programming from First Principles
2+
3+
**Disclaimer: this is an on-going project and is subject to frequent changes.**
4+
5+
This repository hosts my notes and solutions to exercises in the book
6+
[Haskell Programming from First Principles](http://haskellbook.com/).
7+
8+
## Dependencies
9+
10+
The only dependency is [Stack](https://docs.haskellstack.org/en/stable/README/).
11+
Once setup, Stack takes care of any Haskell package dependencies.
12+
13+
## Project structure
14+
15+
This repository is organized as a single Stack project.
16+
Exercise(s) solutions can be found at
17+
```bash
18+
src/<chapter name>/<section name>/<exercise name>.hs
19+
```
20+
Companion test suites (if available) can be found at
21+
```bash
22+
test/<chapter name>/<section name>/<exercise name>Spec.hs
23+
```
24+
25+
## Run test
26+
27+
All test suites can be discovered by `hspec-discover`. To run tests, simply do
28+
29+
```bash
30+
stack test
31+
```
32+
or
33+
```bash
34+
stack --fast test
35+
```
36+
if you want avoid GHC optimization (hence faster).
37+
38+
## Troubleshooting

Setup.hs

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import Distribution.Simple
2+
main = defaultMain

package.yaml

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: haskell-programming-from-first-principles
2+
version: 0.1.0.0
3+
github: "BoeingX/haskell-programming-from-first-principles"
4+
license: BSD3
5+
author: "BoeingX"
6+
maintainer: "[email protected]"
7+
copyright: "BSD3"
8+
9+
extra-source-files:
10+
- README.md
11+
- ChangeLog.md
12+
13+
# Metadata used when publishing your package
14+
# synopsis: Short description of your package
15+
# category: Education
16+
17+
# To avoid duplicated efforts in documentation and dealing with the
18+
# complications of embedding Haddock markup inside cabal files, it is
19+
# common to point users to the README.md file.
20+
description: Please see the README on GitHub at <https://github.com/BoeingX/haskell-programming-from-first-principles#readme>
21+
22+
dependencies:
23+
- base >= 4.7 && < 5
24+
- hspec
25+
- QuickCheck
26+
- checkers
27+
28+
library:
29+
source-dirs: src
30+
31+
tests:
32+
haskell-programming-from-first-principles-test:
33+
main: Spec.hs
34+
source-dirs: test
35+
ghc-options:
36+
- -threaded
37+
- -rtsopts
38+
- -with-rtsopts=-N
39+
dependencies:
40+
- haskell-programming-from-first-principles
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module Applicative.ApplicativeInUse.ConstantExercise (
2+
Constant (..)
3+
) where
4+
5+
newtype Constant a b = Constant { getConstant :: a }
6+
deriving (Eq, Ord, Show)
7+
8+
instance Functor (Constant a) where
9+
fmap _ (Constant a) = Constant a
10+
11+
instance Monoid a => Applicative (Constant a) where
12+
pure _ = Constant mempty
13+
Constant a <*> Constant b = Constant $ a <> b
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module Applicative.ApplicativeInUse.IdentityExercise (
2+
Identity (..)
3+
) where
4+
5+
newtype Identity a = Identity a
6+
deriving (Eq, Ord, Show)
7+
instance Functor Identity where
8+
fmap f (Identity a) = Identity $ f a
9+
instance Applicative Identity where
10+
pure = Identity
11+
Identity f <*> Identity a = Identity $ f a
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module Applicative.ApplicativeInUse.MaybeExercise () where
2+
3+
maybe :: Maybe String
4+
maybe = const <$> Just "Hello" <*> pure "World"
5+
6+
maybe' :: Maybe (Int, Int, String, [Int])
7+
maybe' = (,,,) <$> Just 90 <*> Just 10 <*> Just "Tierness" <*> pure [1, 2, 3]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
module Applicative.ApplicativeInUse.ShortExercises () where
2+
3+
import Data.List (elemIndex)
4+
5+
-- Question 1
6+
added :: Maybe Integer
7+
added = fmap (+3) (lookup 3 $ zip [1, 2, 3] [4, 5, 6])
8+
9+
-- Question 2
10+
y :: Maybe Integer
11+
y = lookup 3 $ zip [1, 2, 3] [4, 5, 6]
12+
13+
z :: Maybe Integer
14+
z = lookup 2 $ zip [1, 2, 3] [4, 5, 6]
15+
16+
tupled :: Maybe (Integer, Integer)
17+
tupled = (,) <$> y <*> z
18+
19+
-- Question 3
20+
x :: Maybe Int
21+
x = elemIndex 3 [1, 2, 3, 4, 5]
22+
23+
y' :: Maybe Int
24+
y' = elemIndex 4 [1, 2, 3, 4, 5]
25+
26+
max' :: Int -> Int -> Int
27+
max' = max
28+
29+
maxed :: Maybe Int
30+
maxed = max' <$> x <*> y'
31+
32+
-- Question 4
33+
xs = [1, 2, 3]
34+
ys = [4, 5, 6]
35+
36+
x' :: Maybe Integer
37+
x' = lookup 3 $ zip xs ys
38+
39+
y'' :: Maybe Integer
40+
y'' = lookup 2 $ zip xs ys
41+
42+
summed :: Maybe Integer
43+
summed = fmap sum $ (,) <$> x' <*> y''

src/Applicative/ApplicativeLaws/.gitkeep

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
module Applicative.ChapterExercises.ApplicativeInstances (
2+
Identity (..)
3+
, Pair (..)
4+
, Two (..)
5+
, Three (..)
6+
, Three' (..)
7+
, Four (..)
8+
, Four' (..)
9+
) where
10+
11+
import Control.Applicative (liftA2, liftA3)
12+
import Test.QuickCheck
13+
import Test.QuickCheck.Checkers
14+
15+
-- Question 1
16+
newtype Identity a = Identity a
17+
deriving (Show, Eq)
18+
19+
instance Applicative Identity where
20+
pure = Identity
21+
Identity f <*> Identity x = Identity $ f x
22+
23+
instance Functor Identity where
24+
fmap f (Identity a) = Identity $ f a
25+
26+
instance (Arbitrary a) => Arbitrary (Identity a) where
27+
arbitrary = Identity <$> arbitrary
28+
29+
instance (Eq a) => EqProp (Identity a) where (=-=) = eq
30+
31+
-- Question 2
32+
data Pair a = Pair a a
33+
deriving (Show, Eq)
34+
35+
instance Functor Pair where
36+
fmap f (Pair a b) = Pair (f a) (f b)
37+
38+
instance Applicative Pair where
39+
pure a = Pair a a
40+
Pair f g <*> Pair x y = Pair (f x) (g y)
41+
42+
instance (Arbitrary a) => Arbitrary (Pair a) where
43+
arbitrary = liftA2 Pair arbitrary arbitrary
44+
45+
instance (Eq a) => EqProp (Pair a) where (=-=) = eq
46+
47+
-- Question 3
48+
data Two a b = Two a b
49+
deriving (Show, Eq)
50+
51+
instance Functor (Two a) where
52+
fmap f (Two a b) = Two a (f b)
53+
54+
instance (Monoid a) => Applicative (Two a) where
55+
pure = Two mempty
56+
Two f g <*> Two x y = Two (f <> x) (g y)
57+
58+
instance (Arbitrary a, Arbitrary b) => Arbitrary (Two a b) where
59+
arbitrary = liftA2 Two arbitrary arbitrary
60+
61+
instance (Eq a, Eq b) => EqProp (Two a b) where (=-=) = eq
62+
63+
-- Question 4
64+
data Three a b c = Three a b c
65+
deriving (Show, Eq)
66+
67+
instance Functor (Three a b) where
68+
fmap f (Three a b c) = Three a b (f c)
69+
70+
instance (Monoid a, Monoid b) => Applicative (Three a b) where
71+
pure = Three mempty mempty
72+
Three f g h <*> Three x y z = Three (f <> x) (g <> y) (h z)
73+
74+
instance (Arbitrary a, Arbitrary b, Arbitrary c) => Arbitrary (Three a b c) where
75+
arbitrary = liftA3 Three arbitrary arbitrary arbitrary
76+
77+
instance (Eq a, Eq b, Eq c) => EqProp (Three a b c) where (=-=) = eq
78+
79+
80+
-- Question 5
81+
data Three' a b = Three' a b b
82+
deriving (Show, Eq)
83+
84+
instance Functor (Three' a) where
85+
fmap f (Three' a b b') = Three' a (f b) (f b')
86+
87+
instance (Monoid a) => Applicative (Three' a) where
88+
pure b = Three' mempty b b
89+
Three' f g h <*> Three' x y z = Three' (f <> x) (g y) (h z)
90+
91+
instance (Arbitrary a, Arbitrary b) => Arbitrary (Three' a b) where
92+
arbitrary = liftA3 Three' arbitrary arbitrary arbitrary
93+
94+
instance (Eq a, Eq b) => EqProp (Three' a b) where (=-=) = eq
95+
96+
97+
-- Question 6
98+
data Four a b c d = Four a b c d
99+
deriving (Show, Eq)
100+
101+
instance Functor (Four a b c) where
102+
fmap f (Four a b c d) = Four a b c (f d)
103+
104+
instance (Monoid a, Monoid b, Monoid c) => Applicative (Four a b c) where
105+
pure = Four mempty mempty mempty
106+
Four f g h i <*> Four x y z w = Four (f <> x) (g <> y) (h <> z) (i w)
107+
108+
instance (Arbitrary a, Arbitrary b, Arbitrary c, Arbitrary d) => Arbitrary (Four a b c d) where
109+
arbitrary = Four <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
110+
111+
instance (Eq a, Eq b, Eq c, Eq d) => EqProp (Four a b c d) where (=-=) = eq
112+
113+
114+
-- Question 7
115+
data Four' a b = Four' a a a b
116+
deriving (Show, Eq)
117+
118+
instance Functor (Four' a) where
119+
fmap f (Four' a a' a'' b) = Four' a a' a'' (f b)
120+
121+
instance (Monoid a) => Applicative (Four' a) where
122+
pure = Four' mempty mempty mempty
123+
Four' f g h i <*> Four' x y z w = Four' (f <> x) (g <> y) (h <> z) (i w)
124+
125+
instance (Arbitrary a, Arbitrary b) => Arbitrary (Four' a b) where
126+
arbitrary = Four' <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
127+
128+
instance (Eq a, Eq b) => EqProp (Four' a b) where (=-=) = eq
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module Applicative.ChapterExercises.Combinations (
2+
stops
3+
, vowels
4+
, combos
5+
) where
6+
7+
import Control.Applicative (liftA3)
8+
9+
stops, vowels :: String
10+
stops = "pbtdkg"
11+
vowels = "aeiou"
12+
13+
combos :: [a] -> [b] -> [c] -> [(a, b, c)]
14+
combos = liftA3 (,,)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
Given a type that has an instance of Applicative, specialize the types of the methods.
2+
3+
1. `[]`
4+
```haskell
5+
pure :: a -> [a]
6+
(<*>) :: [(a -> b)] -> [a] -> [b]
7+
```
8+
9+
2. `IO`
10+
```haskell
11+
pure :: a -> IO a
12+
(<*>) :: IO (a -> b) -> IO a -> IO b
13+
```
14+
15+
3. `(,) a`
16+
```haskell
17+
pure :: a -> (t, a)
18+
(<*>) :: (t, (a -> b)) -> (t, a) -> (t, b)
19+
```
20+
21+
4. `(->) e`
22+
```haskell
23+
pure :: a -> (e -> a)
24+
(<*>) :: (e -> (a -> b)) -> (e -> a) -> (e -> b)
25+
```

src/Applicative/YouKnewThisWasComing/.gitkeep

Whitespace-only changes.

0 commit comments

Comments
 (0)