From 3624c712d72d246f21d4e710cec7c11e052e0326 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Tue, 9 Dec 2025 16:32:32 +0100 Subject: Add the haskell book --- Haskell-book/09/src/Cipher.purs | 15 ++++++++ Haskell-book/09/src/EnumFromTo.purs | 15 ++++++++ Haskell-book/09/src/Exercises.hs | 73 +++++++++++++++++++++++++++++++++++++ Haskell-book/09/src/Exercises.purs | 27 ++++++++++++++ Haskell-book/09/src/Filtering.purs | 8 ++++ Haskell-book/09/src/Main.purs | 9 +++++ Haskell-book/09/src/PoemLines.purs | 42 +++++++++++++++++++++ Haskell-book/09/src/SquareCube.purs | 25 +++++++++++++ Haskell-book/09/src/Zipping.purs | 27 ++++++++++++++ 9 files changed, 241 insertions(+) create mode 100644 Haskell-book/09/src/Cipher.purs create mode 100644 Haskell-book/09/src/EnumFromTo.purs create mode 100644 Haskell-book/09/src/Exercises.hs create mode 100644 Haskell-book/09/src/Exercises.purs create mode 100644 Haskell-book/09/src/Filtering.purs create mode 100644 Haskell-book/09/src/Main.purs create mode 100644 Haskell-book/09/src/PoemLines.purs create mode 100644 Haskell-book/09/src/SquareCube.purs create mode 100644 Haskell-book/09/src/Zipping.purs (limited to 'Haskell-book/09/src') 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) -- cgit v1.2.3