zhaw-fup/Exercises/exercise-5/Solution.hs

128 lines
3.6 KiB
Haskell
Raw Normal View History

2024-06-16 19:34:16 +00:00
import Data.Bits
2024-06-16 18:33:44 +00:00
import Data.Char
2024-06-16 19:34:16 +00:00
import Data.Functor.Contravariant
2024-06-16 19:36:38 +00:00
data Result i o =
2024-06-16 18:33:44 +00:00
Result {
2024-06-16 19:36:38 +00:00
input :: i,
actual :: o,
expected :: o,
2024-06-16 18:33:44 +00:00
result :: Bool
} deriving (Show, Eq, Ord)
--------------------
-- Exercise 1
--------------------
2024-06-16 17:54:14 +00:00
newtype Boxed a = Boxed {unbox :: a}
instance Functor Boxed where
fmap f (Boxed a) = Boxed (f a)
2024-06-16 19:36:38 +00:00
test11 = Result x actual expected (actual == expected)
2024-06-16 17:54:14 +00:00
where
2024-06-16 19:36:38 +00:00
x = 1
2024-06-16 18:33:44 +00:00
actual = unbox (fmap id b)
expected = unbox b
2024-06-16 19:36:38 +00:00
b = Boxed { unbox = x :: Integer }
2024-06-16 17:54:14 +00:00
2024-06-16 18:33:44 +00:00
-- >>> test11
2024-06-16 19:36:38 +00:00
-- Result {input = 1, actual = 1, expected = 1, result = True}
2024-06-16 17:54:14 +00:00
--
2024-06-16 19:36:38 +00:00
test12 = Result x actual expected (actual == expected)
2024-06-16 17:54:14 +00:00
where
2024-06-16 19:36:38 +00:00
x = 1
2024-06-16 18:33:44 +00:00
actual = unbox (fmap (f . g) b)
expected = unbox (fmap f $ fmap g b)
2024-06-16 19:36:38 +00:00
b = Boxed { unbox = x :: Integer }
2024-06-16 17:54:14 +00:00
f = (+9)
g = (*11)
2024-06-16 18:33:44 +00:00
-- >>> test12
2024-06-16 19:36:38 +00:00
-- Result {input = 1, actual = 20, expected = 20, result = True}
2024-06-16 18:33:44 +00:00
--
--------------------
-- Exercise 2
--------------------
newtype FromInt b = FromInt {fun :: Int -> b}
instance Functor FromInt where
fmap f (FromInt b) = FromInt (\ x -> f (b x))
2024-06-16 19:36:38 +00:00
test21 = Result x actual expected (actual == expected)
2024-06-16 18:33:44 +00:00
where
2024-06-16 19:36:38 +00:00
x = 2
2024-06-16 18:33:44 +00:00
actual = ((fun (fmap id converter)) x)
expected = (fun (converter) x)
converter = FromInt {fun = \ val -> val * (-1)}
-- >>> test21
2024-06-16 19:36:38 +00:00
-- Result {input = 2, actual = -2, expected = -2, result = True}
2024-06-16 18:33:44 +00:00
--
2024-06-16 19:36:38 +00:00
test22 = Result x actual expected (actual == expected)
2024-06-16 18:33:44 +00:00
where
2024-06-16 19:36:38 +00:00
x = 7
2024-06-16 18:33:44 +00:00
actual = (fun (fmap g $ fmap f converter)) x
expected = (fun ((g . f) <$> converter)) x
converter = FromInt {fun = \ val -> chr ((ord 'A') + val)}
f = \ char -> char:"B"
g = \ str -> str ++ "C"
-- >>> test22
2024-06-16 19:36:38 +00:00
-- Result {input = 7, actual = "HBC", expected = "HBC", result = True}
2024-06-16 17:54:14 +00:00
--
2024-06-16 19:34:16 +00:00
--------------------
-- Exercise 3
--------------------
newtype ToInt b = ToInt {conv :: b -> Int}
instance Contravariant ToInt where
contramap f (ToInt g) = ToInt (\ value -> g (f value))
strHash :: String -> Int
strHash value = realHash 0 value
where
realHash acc "" = acc
realHash acc (char:str) = realHash (acc + ((ord char) .&. 0b11010110)) str
test3 = [
2024-06-16 19:36:38 +00:00
(Result myStr strExpected strActual (strExpected == strActual)),
(Result [myChar] expected actual (expected == actual))
2024-06-16 19:34:16 +00:00
]
where
-- Create object `toInt` for converting strings to an Int hash (using the "strHash" function)
toInt = ToInt strHash
-- Converting a string to an Int hash using `toInt` should yield
-- the same result like using `strHash` directly
strActual = conv toInt myStr
strExpected = strHash myStr
-- Create a function for converting a `Char` to a `String`
charToStr = \x -> [x]
-- Wrap `toInt` in a (Char -> String) converter using `contramap`
-- effectively using `toInt` as a `Char -> Int` function
actual = conv (contramap charToStr toInt) myChar
-- should yield the same result like using `charToStr` and the original `toInt` directly
expected = conv toInt (charToStr myChar)
-- Value for testing the `toInt` implementation
myStr = "Hello World"
-- Value for testing the `toInt` implementation
-- wrapped in the `charToStr` function
myChar = 'V'
-- Showing the result of the `String` and the `Char` test
-- >>> mapM_ putStrLn (map show test3)
2024-06-16 19:36:38 +00:00
-- Result {input = "Hello World", actual = 712, expected = 712, result = True}
-- Result {input = "V", actual = 86, expected = 86, result = True}
2024-06-16 19:34:16 +00:00
--