Skip to content

Commit 68917db

Browse files
committed
first commit (finished up to chapter 19)
0 parents  commit 68917db

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+177529
-0
lines changed

.gitignore

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Created by https://www.gitignore.io/api/haskell
2+
3+
### Haskell ###
4+
dist
5+
dist-*
6+
cabal-dev
7+
*.o
8+
*.hi
9+
*.chi
10+
*.chs.h
11+
*.dyn_o
12+
*.dyn_hi
13+
.hpc
14+
.hsenv
15+
.cabal-sandbox/
16+
cabal.sandbox.config
17+
*.prof
18+
*.aux
19+
*.hp
20+
*.eventlog
21+
.stack-work/
22+
cabal.project.local

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# haskellbook-exercises

addition/Addition.hs

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
module Addition where
2+
3+
import Test.Hspec
4+
import Test.QuickCheck
5+
6+
7+
main :: IO ()
8+
main = hspec $ do
9+
describe "Addition" $ do
10+
it "1 + 1 is greated than 1" $
11+
((1::Integer) + 1) > 1 `shouldBe` True
12+
it "2 + 2 is equal to 4" $
13+
(2::Integer) + 2 `shouldBe` 4
14+
it "x + 1 is always greater than x" $
15+
property $ \x -> x + 1 > (x::Integer)
16+
describe "Multiplication" $ do
17+
it "3 `mult` 5 is 15" $
18+
mult (3::Integer) 5 `shouldBe` 15
19+
it "3 `mult` 0 is 0" $
20+
mult (3::Integer) 0 `shouldBe` 0
21+
it "0 `mult` 5 is 15" $
22+
mult (0::Integer) 5 `shouldBe` 0
23+
24+
25+
mult :: (Eq a, Num a) => a -> a -> a
26+
mult 0 _ = 0
27+
mult _ 0 = 0
28+
mult x y = x + mult x (y - 1)
29+
30+
31+
genTuple :: (Arbitrary a, Arbitrary b) => Gen (a, b)
32+
genTuple = do
33+
a <- arbitrary
34+
b <- arbitrary
35+
return (a, b)

addition/LICENSE

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
Copyright Author name here (c) 2016
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 Author name here 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.

addition/addition.cabal

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: addition
2+
version: 0.1.0.0
3+
synopsis: Simple project template from stack
4+
description: Please see README.md
5+
homepage: https://github.com/githubuser/addition#readme
6+
license: BSD3
7+
license-file: LICENSE
8+
author: Author name here
9+
maintainer: example@example.com
10+
copyright: 2016 Author name here
11+
category: Web
12+
build-type: Simple
13+
cabal-version: >=1.10
14+
15+
library
16+
exposed-modules: Addition
17+
ghc-options: -Wall -fwarn-tabs
18+
build-depends: base >= 4.7 && < 5
19+
, hspec
20+
, QuickCheck
21+
hs-source-dirs: .
22+
default-language: Haskell2010

addition/stack.yaml

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
flags: {}
2+
extra-package-dbs: []
3+
packages:
4+
- '.'
5+
extra-deps:
6+
- HUnit-1.3.1.1
7+
- QuickCheck-2.8.2
8+
- ansi-terminal-0.6.2.3
9+
- async-2.1.0
10+
- hspec-2.2.3
11+
- hspec-core-2.2.3
12+
- hspec-discover-2.2.3
13+
- hspec-expectations-0.7.2
14+
- primitive-0.6.1.0
15+
- quickcheck-io-0.1.2
16+
- random-1.1
17+
- setenv-0.1.1.3
18+
- stm-2.4.4.1
19+
- tf-random-0.5
20+
resolver: ghc-8.0.1

ch10database.hs

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
module Chapter10Database where
2+
3+
import Data.Time
4+
5+
6+
data DatabaseItem = DbString String
7+
| DbNumber Integer
8+
| DbDate UTCTime
9+
deriving (Eq, Ord, Show)
10+
11+
theDatabase :: [DatabaseItem]
12+
theDatabase =
13+
[
14+
DbDate (UTCTime (fromGregorian 1911 5 1) (secondsToDiffTime 34123))
15+
, DbNumber 9001
16+
, DbString "Hola Mundo!"
17+
, DbDate (UTCTime (fromGregorian 1921 5 1) (secondsToDiffTime 34123))
18+
]
19+
20+
filterDbDate :: [DatabaseItem] -> [UTCTime]
21+
filterDbDate = foldr extractUtcTime []
22+
where extractUtcTime (DbDate utcTime) acc = utcTime : acc
23+
extractUtcTime _ acc = acc
24+
25+
filterDbNumber :: [DatabaseItem] -> [Integer]
26+
filterDbNumber = foldr extractInteger []
27+
where extractInteger (DbNumber int) acc = int : acc
28+
extractInteger _ acc = acc
29+
30+
mostRecent :: [DatabaseItem] -> UTCTime
31+
mostRecent = maximum . filterDbDate
32+
33+
sumDb :: [DatabaseItem] -> Integer
34+
sumDb = sum . filterDbNumber
35+
36+
avgDb :: [DatabaseItem] -> Double
37+
avgDb xs = (fromIntegral . sum) numbers / (fromIntegral . length) numbers
38+
where numbers = filterDbNumber xs
39+
40+
----
41+
42+
stops = "pbtdkg"
43+
vowels = "aeiou"
44+
45+
asd :: [(Char, Char, Char)]
46+
asd = filter (\x -> getSt1 x == 'p') [(st1, v, st2) | st1 <- stops, v <- vowels, st2 <- stops]
47+
where getSt1 (st1, _, _) = st1
48+
49+
myAny :: (a -> Bool) -> [a] -> Bool
50+
myAny p = foldr (\x acc -> acc || p x) False
51+
52+
myMap :: (a -> b) -> [a] -> [b]
53+
myMap f = foldr (\x acc -> f x : acc) []

ch11btree.hs

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
module Chapter11BTree where
2+
3+
4+
data BinaryTree a =
5+
Leaf
6+
| Node (BinaryTree a) a (BinaryTree a)
7+
deriving (Eq, Ord, Show)
8+
9+
insertBT :: Ord a => a -> BinaryTree a -> BinaryTree a
10+
insertBT e Leaf = Node Leaf e Leaf
11+
insertBT e (Node l x r)
12+
| e > x = Node l x (insertBT e r)
13+
| e < x = Node (insertBT e l) x r
14+
| otherwise = Node l x r
15+
16+
mapBT :: (a -> b) -> BinaryTree a -> BinaryTree b
17+
mapBT _ Leaf = Leaf
18+
mapBT f (Node l x r) = Node (mapBT f l) (f x) (mapBT f r)
19+
20+
toListBT :: BinaryTree a -> [a]
21+
toListBT Leaf = []
22+
toListBT (Node l x r) = x : toListBT l ++ toListBT r
23+
24+
foldBT :: (a -> b -> b) -> b -> BinaryTree a -> b
25+
foldBT _ z Leaf = z
26+
foldBT f z (Node l x r) = f x (foldBT f (foldBT f z r) l)

ch11cipher.hs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
module Chapter11Cipher where
2+
3+
import Data.Char
4+
5+
caesarChar :: Int -> Char -> Char
6+
caesarChar rShift char = chr $ ord char + rShift
7+
8+
encrypt :: Int -> String -> String
9+
encrypt rShift = map (caesarChar rShift)
10+
11+
decrypt :: Int -> String -> String
12+
decrypt rShift = map (caesarChar (-rShift))
13+
14+
encrypt' :: String -> String -> String
15+
encrypt' password plainText = map g f
16+
where f = zip (cycle password) plainText
17+
g (key, char) = caesarChar (ord key - ord 'A') char
18+
19+
decrypt' :: String -> String -> String
20+
decrypt' password cypher = map g f
21+
where f = zip (cycle password) cypher
22+
g (key, char) = caesarChar (negate $ ord key - ord 'A') char

ch11huttonrazor.hs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module Chapter11HuttonRazor where
2+
3+
data Expr =
4+
Lit Integer
5+
| Add Expr Expr
6+
| Group Expr
7+
8+
eval :: Expr -> Integer
9+
eval (Lit n) = n
10+
eval (Add lexpr rexpr) = eval lexpr + eval rexpr
11+
eval (Group expr) = eval expr
12+
13+
printExpr :: Expr -> String
14+
printExpr (Lit n) = show n
15+
printExpr (Add lexpr rexpr) = printExpr lexpr ++ " + " ++ printExpr rexpr
16+
printExpr (Group expr) = "(" ++ printExpr expr ++ ")"

ch11jammin.hs

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
module Chapter11Jammin where
2+
3+
import Data.List
4+
5+
data Fruit =
6+
Peach
7+
| Plum
8+
| Apple
9+
| Blackberry
10+
| Banana
11+
deriving (Eq, Show, Ord)
12+
13+
data JamJars = Jam
14+
{
15+
fruit :: Fruit
16+
, cannedCount :: Int
17+
} deriving (Eq, Show, Ord)
18+
19+
allJam :: [JamJars]
20+
allJam = [Jam Peach 3, Jam Apple 2, Jam Plum 0, Jam Blackberry 4, Jam Banana 5, Jam Plum 1, Jam Apple 6]
21+
22+
countCannedJamJars :: [JamJars] -> Int
23+
countCannedJamJars = foldr (\jj acc -> cannedCount jj + acc) 0
24+
25+
mostJam :: [JamJars] -> JamJars
26+
mostJam jjs = foldr maxJj (head jjs) jjs
27+
where maxJj x y = if cannedCount x > cannedCount y then x else y
28+
29+
compareJamFruit :: JamJars -> JamJars -> Ordering
30+
compareJamFruit jj1 jj2 = compare (fruit jj1) (fruit jj2)
31+
32+
groupJam :: [JamJars] -> [[JamJars]]
33+
groupJam = groupBy (\jj1 jj2 -> fruit jj1 == fruit jj2) . sort

ch11phone.hs

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{-# LANGUAGE FlexibleInstances #-}
2+
3+
module Chapter11Phone where
4+
5+
import qualified Data.Char as C
6+
import qualified Data.Text as T
7+
8+
9+
type NextInputCharIsUpper = Bool
10+
type OutputChoices = () -> [Char]
11+
12+
data KeyBuffer = EmptyKeyBuffer | PressedKeyBuffer Char Int OutputChoices deriving (Show)
13+
14+
data TextpadST = TextpadST T.Text KeyBuffer NextInputCharIsUpper deriving (Show)
15+
16+
17+
instance Show OutputChoices where
18+
show f = show (take 5 (f ()) ++ "...")
19+
20+
21+
pressTextpadKey :: TextpadST -> Char -> TextpadST
22+
pressTextpadKey tp key =
23+
case C.toUpper key of
24+
'1' -> appendChar (acceptKeyBuffer tp) '1'
25+
'2' -> pressKey tp '2' (\() -> cycle ['a'..'c'])
26+
'3' -> pressKey tp '3' (\() -> cycle ['d'..'f'])
27+
'4' -> pressKey tp '4' (\() -> cycle ['g'..'i'])
28+
'5' -> pressKey tp '5' (\() -> cycle ['j'..'l'])
29+
'6' -> pressKey tp '6' (\() -> cycle ['m'..'o'])
30+
'7' -> pressKey tp '7' (\() -> cycle ['p'..'s'])
31+
'8' -> pressKey tp '8' (\() -> cycle ['t'..'v'])
32+
'9' -> pressKey tp '9' (\() -> cycle ['w'..'z'])
33+
'*' -> toogleCase tp
34+
'0' -> pressKey tp '0' (\() -> cycle ['+', ' '])
35+
'#' -> pressKey tp '#' (\() -> cycle ['.', ','])
36+
'P' -> acceptKeyBuffer tp
37+
_ -> tp
38+
39+
pressTextpadKeys :: String -> TextpadST
40+
pressTextpadKeys = foldl pressTextpadKey (TextpadST T.empty EmptyKeyBuffer False)
41+
42+
pressKey :: TextpadST -> Char -> OutputChoices -> TextpadST
43+
pressKey (TextpadST txt EmptyKeyBuffer nextInputCharIsUpper) c oc = TextpadST txt (PressedKeyBuffer c 1 oc) nextInputCharIsUpper
44+
pressKey tp@(TextpadST txt (PressedKeyBuffer c' count oc') nextInputCharIsUpper) c oc =
45+
if c == c'
46+
then TextpadST txt (PressedKeyBuffer c' (count + 1) oc') nextInputCharIsUpper
47+
else pressKey (acceptKeyBuffer tp) c oc
48+
49+
toogleCase :: TextpadST -> TextpadST
50+
toogleCase (TextpadST txt keyBuffer nextInputCharIsUpper) = TextpadST txt keyBuffer (not nextInputCharIsUpper)
51+
52+
acceptKeyBuffer :: TextpadST -> TextpadST
53+
acceptKeyBuffer (TextpadST txt EmptyKeyBuffer nextInputCharIsUpper) = TextpadST txt EmptyKeyBuffer nextInputCharIsUpper
54+
acceptKeyBuffer tp@(TextpadST _ (PressedKeyBuffer _ count oc') _) = appendChar tp (oc' () !! (count - 1))
55+
56+
appendChar :: TextpadST -> Char -> TextpadST
57+
appendChar (TextpadST txt _ nextInputCharIsUpper) c = TextpadST (T.snoc txt (setCase c)) EmptyKeyBuffer False
58+
where setCase = if nextInputCharIsUpper then C.toUpper else id

ch11prog.hs

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
module Chapter11Programming where
2+
3+
4+
data OperatingSystem =
5+
GnuPlusLinux
6+
| OpenBSD
7+
| Mac
8+
| Windows
9+
deriving (Eq, Show, Enum)
10+
11+
data ProgrammingLanguage =
12+
Haskell
13+
| Agda
14+
| Idris
15+
| PureScript
16+
deriving (Eq, Show, Enum)
17+
18+
data Programmer =
19+
Programmer {
20+
os :: OperatingSystem
21+
, lang :: ProgrammingLanguage
22+
} deriving (Eq, Show)
23+
24+
allOperatingSystems :: [OperatingSystem]
25+
allOperatingSystems = enumFrom $ toEnum 0
26+
27+
allLanguages :: [ProgrammingLanguage]
28+
allLanguages = enumFrom $ toEnum 0
29+
30+
allProgrammers :: [Programmer]
31+
allProgrammers = [Programmer os' lang' | os' <- allOperatingSystems, lang' <- allLanguages]

0 commit comments

Comments
 (0)