aboutsummaryrefslogtreecommitdiff
path: root/Haskell-book/14/morse/src
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2025-12-11 10:28:11 +0100
committerEugen Wissner <belka@caraus.de>2025-12-11 10:28:11 +0100
commit98329e0a3dd4f78b5d815ac3896272ec70904901 (patch)
tree80f9c56cfe2ac20232358f236d32e84bd683be1b /Haskell-book/14/morse/src
parent3624c712d72d246f21d4e710cec7c11e052e0326 (diff)
downloadbook-exercises-98329e0a3dd4f78b5d815ac3896272ec70904901.tar.gz
Add remaining haskell book exercises
Diffstat (limited to 'Haskell-book/14/morse/src')
-rw-r--r--Haskell-book/14/morse/src/Main.hs59
-rw-r--r--Haskell-book/14/morse/src/Morse.hs68
-rw-r--r--Haskell-book/14/morse/src/WordNumber.hs26
3 files changed, 153 insertions, 0 deletions
diff --git a/Haskell-book/14/morse/src/Main.hs b/Haskell-book/14/morse/src/Main.hs
new file mode 100644
index 0000000..1f73b90
--- /dev/null
+++ b/Haskell-book/14/morse/src/Main.hs
@@ -0,0 +1,59 @@
+module Main where
+
+import Control.Monad (forever, when)
+import Data.List (intercalate)
+import Data.Traversable (traverse)
+import Morse (stringToMorse, morseToChar)
+import System.Environment (getArgs)
+import System.Exit (exitFailure, exitSuccess)
+import System.IO (hGetLine, hIsEOF, stdin)
+
+convertToMorse :: IO ()
+convertToMorse = forever $ do
+ weAreDone <- hIsEOF stdin
+ when weAreDone exitSuccess
+
+ line <- hGetLine stdin
+ convertLine line
+
+ where convertLine line = do
+ let morse = stringToMorse line
+ case morse of
+ (Just str) -> putStrLn (intercalate " " str)
+ Nothing -> do
+ putStrLn $ "ERROR: " ++ line
+ exitFailure
+
+convertFromMorse :: IO ()
+convertFromMorse = forever $ do
+ weAreDone <- hIsEOF stdin
+ when weAreDone exitSuccess
+
+ line <- hGetLine stdin
+ convertLine line
+
+ where
+ convertLine line = do
+ let decoded :: Maybe String
+ decoded = traverse morseToChar (words line)
+
+ case decoded of
+ (Just s) -> putStrLn s
+ Nothing -> do
+ putStrLn $ "ERROR: " ++ line
+ exitFailure
+
+main :: IO ()
+main = do
+ mode <- getArgs
+ case mode of
+ [arg] ->
+ case arg of
+ "from" -> convertFromMorse
+ "to" -> convertToMorse
+ _ -> argError
+ _ -> argError
+
+ where argError = do
+ putStrLn "Please specify the first argument as being 'from' or 'to' morse, such as: morse to"
+ exitFailure \ No newline at end of file
diff --git a/Haskell-book/14/morse/src/Morse.hs b/Haskell-book/14/morse/src/Morse.hs
new file mode 100644
index 0000000..03193e5
--- /dev/null
+++ b/Haskell-book/14/morse/src/Morse.hs
@@ -0,0 +1,68 @@
+module Morse
+ ( Morse
+ , charToMorse
+ , morseToChar
+ , stringToMorse
+ , letterToMorse
+ , morseToLetter
+ ) where
+
+import qualified Data.Map as M
+
+type Morse = String
+
+letterToMorse :: (M.Map Char Morse)
+letterToMorse = M.fromList [
+ ('a', ".-")
+ , ('b', "-...")
+ , ('c', "-.-.")
+ , ('d', "-..")
+ , ('e', ".")
+ , ('f', "..-.")
+ , ('g', "--.")
+ , ('h', "....")
+ , ('i', "..")
+ , ('j', ".---")
+ , ('k', "-.-")
+ , ('l', ".-..")
+ , ('m', "--")
+ , ('n', "-.")
+ , ('o', "---")
+ , ('p', ".--.")
+ , ('q', "--.-")
+ , ('r', ".-.")
+ , ('s', "...")
+ , ('t', "-")
+ , ('u', "..-")
+ , ('v', "...-")
+ , ('w', ".--")
+ , ('x', "-..-")
+ , ('y', "-.--")
+ , ('z', "--..")
+ , ('1', ".----")
+ , ('2', "..---")
+ , ('3', "...--")
+ , ('4', "....-")
+ , ('5', ".....")
+ , ('6', "-....")
+ , ('7', "--...")
+ , ('8', "---..")
+ , ('9', "----.")
+ , ('0', "-----")
+ ]
+
+morseToLetter :: M.Map Morse Char
+morseToLetter =
+ M.foldWithKey (flip M.insert) M.empty
+ letterToMorse
+
+charToMorse :: Char -> Maybe Morse
+charToMorse c =
+ M.lookup c letterToMorse
+
+stringToMorse :: String -> Maybe [Morse]
+stringToMorse s =
+ sequence $ fmap charToMorse s
+
+morseToChar :: Morse -> Maybe Char
+morseToChar m = M.lookup m morseToLetter \ No newline at end of file
diff --git a/Haskell-book/14/morse/src/WordNumber.hs b/Haskell-book/14/morse/src/WordNumber.hs
new file mode 100644
index 0000000..5b25ee2
--- /dev/null
+++ b/Haskell-book/14/morse/src/WordNumber.hs
@@ -0,0 +1,26 @@
+module WordNumber where
+
+import Data.List (unfoldr, intercalate)
+import Data.Maybe (Maybe(..))
+
+digitToWord :: Int -> String
+digitToWord 0 = "zero"
+digitToWord 1 = "one"
+digitToWord 2 = "two"
+digitToWord 3 = "three"
+digitToWord 4 = "four"
+digitToWord 5 = "five"
+digitToWord 6 = "six"
+digitToWord 7 = "seven"
+digitToWord 8 = "eight"
+digitToWord 9 = "nine"
+digitToWord _ = ""
+
+digits :: Int -> [Int]
+digits n = reverse $ unfoldr unfold n
+ where unfold x
+ | x == 0 = Nothing
+ | otherwise = Just ((mod x 10), (div x 10))
+
+wordNumber :: Int -> String
+wordNumber n = intercalate "-" $ map digitToWord (digits n) \ No newline at end of file