summaryrefslogtreecommitdiff
path: root/Haskell-book/09
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2025-12-09 16:32:32 +0100
committerEugen Wissner <belka@caraus.de>2025-12-09 16:32:32 +0100
commit3624c712d72d246f21d4e710cec7c11e052e0326 (patch)
treef385cb51c72a0c5eeb2057609b75f5f8c6c4f272 /Haskell-book/09
parentc95abc31d62e296db4f1b537e3de440dd40defd1 (diff)
downloadbook-exercises-3624c712d72d246f21d4e710cec7c11e052e0326.tar.gz
Add the haskell book
Diffstat (limited to 'Haskell-book/09')
-rw-r--r--Haskell-book/09/.gitignore8
-rw-r--r--Haskell-book/09/bower.json21
-rw-r--r--Haskell-book/09/src/Cipher.purs15
-rw-r--r--Haskell-book/09/src/EnumFromTo.purs15
-rw-r--r--Haskell-book/09/src/Exercises.hs73
-rw-r--r--Haskell-book/09/src/Exercises.purs27
-rw-r--r--Haskell-book/09/src/Filtering.purs8
-rw-r--r--Haskell-book/09/src/Main.purs9
-rw-r--r--Haskell-book/09/src/PoemLines.purs42
-rw-r--r--Haskell-book/09/src/SquareCube.purs25
-rw-r--r--Haskell-book/09/src/Zipping.purs27
-rw-r--r--Haskell-book/09/test/Main.purs9
12 files changed, 279 insertions, 0 deletions
diff --git a/Haskell-book/09/.gitignore b/Haskell-book/09/.gitignore
new file mode 100644
index 0000000..9623fa5
--- /dev/null
+++ b/Haskell-book/09/.gitignore
@@ -0,0 +1,8 @@
+/bower_components/
+/node_modules/
+/.pulp-cache/
+/output/
+/generated-docs/
+/.psc*
+/.purs*
+/.psa*
diff --git a/Haskell-book/09/bower.json b/Haskell-book/09/bower.json
new file mode 100644
index 0000000..f13cca6
--- /dev/null
+++ b/Haskell-book/09/bower.json
@@ -0,0 +1,21 @@
+{
+ "name": "09",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "output"
+ ],
+ "dependencies": {
+ "purescript-prelude": "^3.1.0",
+ "purescript-console": "^3.0.0",
+ "purescript-lists": "^4.10.0",
+ "purescript-arrays": "^4.2.1",
+ "purescript-maybe": "^3.0.0",
+ "purescript-enums": "^3.2.1",
+ "purescript-strings": "^3.3.1"
+ },
+ "devDependencies": {
+ "purescript-psci-support": "^3.0.0"
+ }
+}
diff --git a/Haskell-book/09/src/Cipher.purs b/Haskell-book/09/src/Cipher.purs
new file mode 100644
index 0000000..d5605c2
--- /dev/null
+++ b/Haskell-book/09/src/Cipher.purs
@@ -0,0 +1,15 @@
+module Cipher where
+
+import Data.Char (fromCharCode, toCharCode)
+import Data.String (fromCharArray, toCharArray)
+import Prelude
+
+caesar :: Int -> String -> String
+caesar key s = fromCharArray $ map shiftRight (toCharArray s)
+ where shiftRight char = fromCharCode $ mod (ord char) 26
+ ord = (add key) <<< toCharCode
+
+unCaesar :: Int -> String -> String
+unCaesar key s = fromCharArray $ map shiftLeft (toCharArray s)
+ where shiftLeft char = fromCharCode $ ord char
+ ord chr = ((toCharCode chr) - (mod key 26)) + 26
diff --git a/Haskell-book/09/src/EnumFromTo.purs b/Haskell-book/09/src/EnumFromTo.purs
new file mode 100644
index 0000000..f389c31
--- /dev/null
+++ b/Haskell-book/09/src/EnumFromTo.purs
@@ -0,0 +1,15 @@
+module EnumFromTo where
+
+import Data.Array ((:), reverse)
+import Data.Enum (class Enum, succ)
+import Data.Maybe (Maybe(..))
+import Prelude
+
+enumFromTo :: forall a. Enum a => a -> a -> Array a
+enumFromTo start end = reverse $ enumFromTo' [] (Just start)
+ where enumFromTo' :: Array a -> Maybe a -> Array a
+ enumFromTo' acc (Just start')
+ | start' > end = acc
+ | start' == end = start' : acc
+ | otherwise = enumFromTo' (start' : acc) (succ start')
+ enumFromTo' acc Nothing = acc
diff --git a/Haskell-book/09/src/Exercises.hs b/Haskell-book/09/src/Exercises.hs
new file mode 100644
index 0000000..52ff797
--- /dev/null
+++ b/Haskell-book/09/src/Exercises.hs
@@ -0,0 +1,73 @@
+module Exercises where
+
+-- direct recursion, not using (&&)
+myAnd :: [Bool] -> Bool
+myAnd [] = True
+myAnd (x:xs) =
+ if x == False
+ then False
+ else myAnd xs
+
+-- direct recursion, using (&&)
+myAnd' :: [Bool] -> Bool
+myAnd' [] = True
+myAnd' (x:xs) = x && myAnd' xs
+
+-- 1
+myOr :: [Bool] -> Bool
+myOr [] = False
+myOr (x:xs) = x || myOr xs
+
+-- 2
+myAny :: (a -> Bool) -> [a] -> Bool
+myAny f xs = myOr $ map f xs
+
+-- 3
+myElem :: Eq a => a -> [a] -> Bool
+myElem _ [] = False
+myElem y (x:xs) = (x == y) || (myElem y xs)
+
+-- 4
+myReverse :: [a] -> [a]
+myReverse [] = []
+myReverse (x:xs) = (myReverse xs) ++ [x]
+
+-- 5
+squish :: [[a]] -> [a]
+squish = squish' []
+ where squish' acc [] = acc
+ squish' acc (x:xs) = x ++ (squish' acc xs)
+
+-- 6
+squishMap :: (a -> [b]) -> [a] -> [b]
+squishMap _ [] = []
+squishMap f (x:xs) = (f x) ++ (squishMap f xs)
+
+-- 7
+squishAgain :: [[a]] -> [a]
+squishAgain x = squishMap id x
+
+-- 8
+myMaximumBy :: (a -> a -> Ordering)
+ -> [a] -> a
+myMaximumBy f (x:xs) = myMaximumBy' x xs
+ where myMaximumBy' m [] = m
+ myMaximumBy' m (y:ys)
+ | f y m == GT = myMaximumBy' y ys
+ | otherwise = myMaximumBy' m ys
+
+-- 9
+myMinimumBy :: (a -> a -> Ordering)
+ -> [a] -> a
+myMinimumBy f (x:xs) = myMinimumBy' x xs
+ where myMinimumBy' m [] = m
+ myMinimumBy' m (y:ys)
+ | f y m == LT = myMinimumBy' y ys
+ | otherwise = myMinimumBy' m ys
+
+-- 10
+myMaximum :: (Ord a) => [a] -> a
+myMaximum = myMaximumBy compare
+
+myMinimum :: (Ord a) => [a] -> a
+myMinimum = myMinimumBy compare
diff --git a/Haskell-book/09/src/Exercises.purs b/Haskell-book/09/src/Exercises.purs
new file mode 100644
index 0000000..b18cf24
--- /dev/null
+++ b/Haskell-book/09/src/Exercises.purs
@@ -0,0 +1,27 @@
+module Exercises where
+
+import Data.Array (filter)
+import Data.Char (toLower, toUpper)
+import Data.Maybe (Maybe(..))
+import Data.String (fromCharArray, toCharArray, uncons)
+import Prelude
+
+-- 2
+filterUppercase :: String -> String
+filterUppercase s = fromCharArray $ filter (\x -> toLower x /= x) (toCharArray s)
+
+-- 3
+capitalize :: String -> String
+capitalize s = maybeCapitalize $ uncons s
+ where maybeCapitalize Nothing = ""
+ maybeCapitalize (Just {head, tail}) = (fromCharArray $ [ toUpper head ]) <> tail
+
+-- 4
+capitalize' :: String -> String
+capitalize' s = fromCharArray $ map toUpper $ toCharArray s
+
+-- 5
+firstLetter :: String -> Maybe Char
+firstLetter = firstLetter' <<< uncons
+ where firstLetter' Nothing = Nothing
+ firstLetter' (Just {head, tail}) = Just $ toUpper head
diff --git a/Haskell-book/09/src/Filtering.purs b/Haskell-book/09/src/Filtering.purs
new file mode 100644
index 0000000..81257a8
--- /dev/null
+++ b/Haskell-book/09/src/Filtering.purs
@@ -0,0 +1,8 @@
+module Filtering where
+
+import Data.Array (filter)
+import Data.String (split, Pattern(..))
+import Prelude
+
+myFilter :: String -> Array String
+myFilter input = filter (\x -> x /= "a" && x /= "the") (split (Pattern " ") input)
diff --git a/Haskell-book/09/src/Main.purs b/Haskell-book/09/src/Main.purs
new file mode 100644
index 0000000..abe68ec
--- /dev/null
+++ b/Haskell-book/09/src/Main.purs
@@ -0,0 +1,9 @@
+module Main where
+
+import Prelude
+import Control.Monad.Eff (Eff)
+import Control.Monad.Eff.Console (CONSOLE, log)
+
+main :: forall e. Eff (console :: CONSOLE | e) Unit
+main = do
+ log "Hello sailor!"
diff --git a/Haskell-book/09/src/PoemLines.purs b/Haskell-book/09/src/PoemLines.purs
new file mode 100644
index 0000000..05a9a86
--- /dev/null
+++ b/Haskell-book/09/src/PoemLines.purs
@@ -0,0 +1,42 @@
+module PoemLines where
+
+import Data.Array ((:))
+import Data.String (takeWhile, dropWhile, drop)
+import Prelude
+
+splitWith :: Char -> String -> Array String
+splitWith _ "" = []
+splitWith sep s = (takeWhile cond s) : (splitWith sep $ drop 1 $ dropWhile cond s)
+ where cond x = x /= sep
+
+myWords :: String -> Array String
+myWords = splitWith ' '
+
+firstSen :: String
+firstSen = "Tyger Tyger, burning bright\n"
+secondSen :: String
+secondSen = "In the forests of the night\n"
+thirdSen :: String
+thirdSen = "What immortal hand or eye\n"
+fourthSen :: String
+fourthSen = "Could frame thy fearful symmetry?"
+
+sentences :: String
+sentences = firstSen <> secondSen <> thirdSen <> fourthSen
+-- putStrLn sentences -- should print
+-- Tyger Tyger, burning bright
+-- In the forests of the night
+-- What immortal hand or eye
+-- Could frame thy fearful symmetry?
+
+myLines :: String -> Array String
+myLines = splitWith '\n'
+
+got :: Array String
+got = myLines sentences
+
+shouldEqual :: Array String
+shouldEqual = [ "Tyger Tyger, burning bright"
+ , "In the forests of the night"
+ , "What immortal hand or eye"
+ , "Could frame thy fearful symmetry?" ]
diff --git a/Haskell-book/09/src/SquareCube.purs b/Haskell-book/09/src/SquareCube.purs
new file mode 100644
index 0000000..6316b4d
--- /dev/null
+++ b/Haskell-book/09/src/SquareCube.purs
@@ -0,0 +1,25 @@
+module SquareCube where
+
+import Control.MonadZero (guard)
+import Data.Array ((..))
+import Data.Int (pow)
+import Data.Tuple (Tuple(..))
+import Prelude
+
+mySqr :: Array Int
+mySqr = do
+ x <- 1 .. 5
+ pure $ pow x 2
+
+myCube :: Array Int
+myCube = do
+ y <- 1 .. 5
+ pure $ pow y 3
+
+mySqrCube :: Array (Tuple Int Int)
+mySqrCube = do
+ x <- mySqr
+ y <- myCube
+ guard $ x < 50
+ guard $ y < 50
+ pure $ Tuple x y
diff --git a/Haskell-book/09/src/Zipping.purs b/Haskell-book/09/src/Zipping.purs
new file mode 100644
index 0000000..32fe6da
--- /dev/null
+++ b/Haskell-book/09/src/Zipping.purs
@@ -0,0 +1,27 @@
+module Zipping where
+
+import Data.Array (head, tail, (:))
+import Data.Maybe (Maybe(..))
+import Data.Tuple (Tuple(..))
+
+-- 1
+zip :: forall a b. Array a -> Array b -> Array (Tuple a b)
+zip a b = f (head a) (head b) (tail a) (tail b)
+ where f Nothing _ _ _ = []
+ f _ Nothing _ _ = []
+ f _ _ Nothing _ = []
+ f _ _ _ Nothing = []
+ f (Just x) (Just y) (Just xs) (Just ys) = (Tuple x y) : (f (head xs) (head ys) (tail xs) (tail ys))
+
+-- 2
+zipWith :: forall a b c. (a -> b -> c) -> Array a -> Array b -> Array c
+zipWith f a b = f' (head a) (head b) (tail a) (tail b)
+ where f' Nothing _ _ _ = []
+ f' _ Nothing _ _ = []
+ f' _ _ Nothing _ = []
+ f' _ _ _ Nothing = []
+ f' (Just x) (Just y) (Just xs) (Just ys) = (f x y) : (f' (head xs) (head ys) (tail xs) (tail ys))
+
+-- 3
+zip' :: forall a b. Array a -> Array b -> Array (Tuple a b)
+zip' = zipWith (\a b -> Tuple a b)
diff --git a/Haskell-book/09/test/Main.purs b/Haskell-book/09/test/Main.purs
new file mode 100644
index 0000000..845d0f4
--- /dev/null
+++ b/Haskell-book/09/test/Main.purs
@@ -0,0 +1,9 @@
+module Test.Main where
+
+import Prelude
+import Control.Monad.Eff (Eff)
+import Control.Monad.Eff.Console (CONSOLE, log)
+
+main :: forall e. Eff (console :: CONSOLE | e) Unit
+main = do
+ log "You should add some tests."