Skip to content

Commit 94f455a

Browse files
committed
Add work done for Chapter 16
1 parent b462b18 commit 94f455a

16 files changed

+496
-0
lines changed

ch16/be-kind.txt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Exercises: Be Kind
2+
3+
Given a type signature, determine the kinds of each type variable:
4+
5+
1. What's the kind of a?
6+
7+
a -> a
8+
9+
Ans: *, since the kind of (->) is * -> * -> *.
10+
11+
2. What are the kinds of b and T? (The T is capitalized on purpose!)
12+
13+
a -> b a -> T (b a)
14+
15+
Ans: a has kind *, b a has kind *. So, b has kind * -> *. Also, T has kind
16+
* -> *.
17+
18+
3. What's the kind of c?
19+
20+
c a b -> c b a
21+
22+
Ans: c a b has kind *. So, c has kind * -> * -> *.

ch16/constant.hs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
newtype Constant a b
2+
= Constant { getConstant :: a }
3+
deriving (Eq, Show)
4+
-- N.B. b is a phantom type
5+
-- i.e. it has no corresponding witness at the value/term level
6+
7+
8+
instance Functor (Constant a) where
9+
fmap _ (Constant a) = Constant a
10+
-- Initially I had
11+
--
12+
-- fmap _ c = c
13+
--
14+
-- But, that doesn't work since f :: b -> c and c :: Constant a b. Hence,
15+
-- the result type should be Constant a c which it isn't if we simply
16+
-- return c. That's why we have to deconstruct the type and then rebuild
17+
-- it and return the result.

ch16/functors.hs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
-- 1
2+
-- data FixMePls
3+
-- = FixMe
4+
-- | Pls
5+
-- deriving (Eq, Show)
6+
--
7+
--
8+
-- instance Functor FixMePls where
9+
-- fmap = error "it doesn't matter, it won't compile"
10+
11+
-- 2
12+
-- data FixMePls a
13+
-- = FixMe
14+
-- | Pls a
15+
-- deriving (Eq, Show)
16+
--
17+
--
18+
-- instance Functor FixMePls where
19+
-- fmap = error "it doesn't matter, it won't compile"
20+
21+
-- 3
22+
data FixMePls a
23+
= FixMe
24+
| Pls a
25+
deriving (Eq, Show)
26+
27+
28+
instance Functor FixMePls where
29+
fmap _ FixMe = FixMe
30+
fmap f (Pls a) = Pls (f a)
31+
32+
-- 4
33+
-- data FixMePls a
34+
-- = FixMe
35+
-- | Pls a
36+
-- deriving (Eq, Show)
37+
--
38+
--
39+
-- instance Functor (FixMePls a) where
40+
-- fmap _ FixMe = FixMe
41+
-- fmap f (Pls a) = Pls (f a)

ch16/heavy-lifting.hs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
module HeavyLifting where
2+
3+
-- Exercises: Heavy Lifting
4+
5+
-- 1.
6+
-- a = (+1) $ read "[1]" :: [Int]
7+
-- a = [2]
8+
a = fmap (+1) $ read "[1]" :: [Int]
9+
10+
11+
-- 2.
12+
-- b = (++ "lol") (Just ["Hi,", "Hello"])
13+
-- b = Just ["Hi,lol","Hellolol"]
14+
b = (fmap . fmap) (++ "lol") (Just ["Hi,", "Hello"])
15+
16+
17+
-- 3.
18+
-- c = (*2) (\x -> x - 2)
19+
-- c 1 = -2
20+
c = fmap (*2) (\x -> x - 2)
21+
22+
23+
-- 4.
24+
-- d = ((return '1' ++) . show) (\x -> [x, 1..3])
25+
-- d 0 = "1[0,1,2,3]"
26+
d = fmap ((return '1' ++) . show) (\x -> [x, 1..3])
27+
28+
29+
-- 5.
30+
-- e :: IO Integer
31+
-- e = let ioi = readIO "1" :: IO Integer
32+
-- changed = read ("123"++) show ioi
33+
-- in (*3) changed
34+
-- > e
35+
-- 3693
36+
e :: IO Integer
37+
e =
38+
let
39+
ioi = readIO "1" :: IO Integer
40+
changed = fmap (read . ("123" ++) . show) ioi
41+
in
42+
fmap (*3) changed

ch16/io-functor.hs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module IOFunctor where
2+
3+
4+
main :: IO ()
5+
main = putStr "> " >> getInt >>= (putStrLn . show)
6+
7+
8+
getInt :: IO Int
9+
getInt = fmap read getLine

ch16/more-structure.hs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
-- 16.13 More structure, more functors
2+
3+
data Wrap f a
4+
= Wrap (f a)
5+
deriving (Eq, Show)
6+
-- This looks so strange to me
7+
--
8+
-- But let's try to break it down
9+
-- f and a are types
10+
-- (f a) has to mean that f :: * -> * and a :: *
11+
--
12+
-- So, Wrap Maybe Int is a possible type
13+
--
14+
-- let a = 1 :: Int
15+
-- let x = Wrap (Just a) :: Wrap Maybe Int
16+
17+
18+
instance Functor f => Functor (Wrap f) where
19+
-- f :: a -> b
20+
-- fa :: f a
21+
--
22+
-- Hence, we need to fmap f over fa. But, that would mean
23+
-- we need f to be a Functor.
24+
--
25+
-- Thus,
26+
fmap f (Wrap fa) = Wrap (fmap f fa)

ch16/natural-transformation.hs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{-# LANGUAGE RankNTypes #-}
2+
3+
module NaturalTransformation where
4+
5+
-- nat :: (f -> g) -> f a -> g a
6+
-- This type is impossible since f and g have kind * -> * and functions only
7+
-- take types of kind *.
8+
9+
type Nat f g = forall a. f a -> g a
10+
11+
12+
-- This'll work
13+
maybeToList :: Nat Maybe []
14+
maybeToList Nothing = []
15+
maybeToList (Just a) = [a]
16+
17+
18+
-- This will not work, not allowed.
19+
-- degenerateMtl :: Nat Maybe []
20+
-- degenerateMtl Nothing = []
21+
-- degenerateMtl (Just a) = [a+1]
22+
23+
24+
-- We can try to do it without using RankNTypes but then we have no way to
25+
-- disallow modifying the container's contents
26+
-- type Nat f g a = f a -> g a
27+
--
28+
--
29+
-- -- This'll work
30+
-- maybeToList :: Nat Maybe [] a
31+
-- maybeToList Nothing = []
32+
-- maybeToList (Just a) = [a]
33+
--
34+
--
35+
-- -- But this will too if we tell it
36+
-- -- 'a' is Num a => a
37+
-- degenerateMtl :: Num a => Nat Maybe [] a
38+
-- degenerateMtl Nothing = []
39+
-- degenerateMtl (Just a) = [a+1]

ch16/possibly.hs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
-- Exercise: Possibly
2+
3+
data Possibly a
4+
= LolNope
5+
| Yeppers a
6+
deriving (Eq, Show)
7+
8+
9+
instance Functor Possibly where
10+
fmap f LolNope = LolNope
11+
fmap f (Yeppers a) = Yeppers (f a)

ch16/qcFunctorInstances/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.stack-work/

ch16/qcFunctorInstances/LICENSE

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
Copyright Dwayne Crooks (c) 2017
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 Dwayne Crooks 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.

ch16/qcFunctorInstances/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# qcFunctorInstances

ch16/qcFunctorInstances/Setup.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import Distribution.Simple
2+
main = defaultMain
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: qcFunctorInstances
2+
version: 0.1.0.0
3+
homepage: https://github.com/dwayne/qcFunctorInstances#readme
4+
license: BSD3
5+
license-file: LICENSE
6+
author: Dwayne Crooks
7+
maintainer: me@dwaynecrooks.com
8+
copyright: 2017 Dwayne Crooks
9+
category: Text
10+
build-type: Simple
11+
cabal-version: >=1.10
12+
extra-source-files: README.md
13+
14+
executable qcFunctorInstances
15+
hs-source-dirs: src
16+
main-is: Main.hs
17+
default-language: Haskell2010
18+
build-depends: base >= 4.7 && < 5
19+
, QuickCheck

0 commit comments

Comments
 (0)