Add the haskell book

This commit is contained in:
2025-12-09 16:32:32 +01:00
parent c95abc31d6
commit 3624c712d7
67 changed files with 1576 additions and 0 deletions

8
Haskell-book/09/.gitignore vendored Normal file
View File

@@ -0,0 +1,8 @@
/bower_components/
/node_modules/
/.pulp-cache/
/output/
/generated-docs/
/.psc*
/.purs*
/.psa*

View File

@@ -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"
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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!"

View File

@@ -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?" ]

View File

@@ -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

View File

@@ -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)

View File

@@ -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."