----------------------------------------------------------------------------- ----------------------------------------------------------------------------- -- | -- Module : Chapter03 -- Description : Types and Entities -- -- Copyright : (c) Eric Zoerner, 2023 -- License : BSD3 -- Maintainer : eric.zoerner@proton.me module Chapter03 where ------------------ -- * Exercise 3.1 ------------------ -- $ex31 -- __(a)__ @(False || (True && False)) || True@ -- -- >:: Bool -- -- __(b)__ @((2 / 3) / 4) == ((4 / 3) /2)@ -- -- >:: Bool -- -- __(c)__ @((7 - (5 / 4)) > 6) || (((2 ^ 5) - 1) == 31)@ -- -- >:: Bool -- -- __(d)__ @2 < 3 < 4@ -- -- /Not well formed: cannot operate on Bool with comparison operators./ -- -- __(e)__ @(2 < 3) || (3 < 4)@ -- -- >:: Bool -- -- __(f)__ @2 && 3 < 4@ -- -- /Not well formed: cannot operate on numeric types with logical && operator./ ------------------ -- * Exercise 3.2 ------------------ -- | @f(x) = { 0, x ≤ 0; x, x > 0}@ f :: Double -> Double f :: Double -> Double f Double x = if Double x Double -> Double -> Bool forall a. Ord a => a -> a -> Bool <= Double 0 then Double 0 else Double x -- | @E(r) = { r, r ≤ 1; 1/r², r > 1}@ e :: Double -> Double e :: Double -> Double e Double r = if Double r Double -> Double -> Bool forall a. Ord a => a -> a -> Bool <= Double 1 then Double r else Double 1 Double -> Double -> Double forall a. Fractional a => a -> a -> a / Double r Double -> Double -> Double forall a. Floating a => a -> a -> a ** Double 2 -- * Exercise 3.3 -- | Returns 'True' if the input character is @\'X\'@ or @\'Y\'@ -- or else 'False'. -- -- >>> isXorY 'X' -- True -- >>> isXorY 'Y' -- True -- >>> isXorY 'Z' -- False isXorY :: Char -> Bool isXorY :: Char -> Bool isXorY Char 'X' = Bool True isXorY Char 'Y' = Bool True isXorY Char _ = Bool False ------------------ -- * Exercise 3.4 ------------------ -- | Returns @100@ if the person is checking bags and @0@ if not. -- Implemented with @if-then-else@. bagFee :: Bool -> Int bagFee :: Bool -> Int bagFee Bool isCheckingBags = if Bool isCheckingBags then Int 100 else Int 0 -- | Returns @100@ if the person is checking bags and @0@ if not. -- Implemented with pattern matching on the input. bagFee2 :: Bool -> Int bagFee2 :: Bool -> Int bagFee2 Bool True = Int 100 bagFee2 Bool _ = Int 0 ------------------ -- * Exercise 3.5 ------------------ -- | Returns 'True' if the given integer is greater than 50 or else 'False' greaterThan50 :: Integer -> Bool greaterThan50 :: Integer -> Bool greaterThan50 Integer n = Integer n Integer -> Integer -> Bool forall a. Ord a => a -> a -> Bool > Integer 50 ------------------ -- * Exercise 3.6 ------------------ -- | Double the score without going over 100 -- -- >>> amazingCurve 30 -- 60 -- >>> amazingCurve 80 -- 100 amazingCurve :: Int -> Int amazingCurve :: Int -> Int amazingCurve Int score = Int -> Int -> Int forall a. Ord a => a -> a -> a min Int 100 (Int score Int -> Int -> Int forall a. Num a => a -> a -> a * Int 2) ------------------ -- * Exercise 3.7 ------------------ -- $ex37 -- >>> :type bagFee False -- bagFee False :: Int -- -- >>> bagFee False -- 0 ------------------ -- * Exercise 3.8 ------------------ -- | @circleRadius = 3.5@ circleRadius :: Double circleRadius :: Double circleRadius = Double 3.5 -- | @cot x = 1 / tan x@ cot :: Double -> Double cot :: Double -> Double cot Double x = Double 1 Double -> Double -> Double forall a. Fractional a => a -> a -> a / Double -> Double forall a. Floating a => a -> a tan Double x -- | @fe epsilon = epsilon * tan (epsilon * pi / 2)@ fe :: Double -> Double fe :: Double -> Double fe Double epsilon = Double epsilon Double -> Double -> Double forall a. Num a => a -> a -> a * Double -> Double forall a. Floating a => a -> a tan (Double epsilon Double -> Double -> Double forall a. Num a => a -> a -> a * Double forall a. Floating a => a pi Double -> Double -> Double forall a. Fractional a => a -> a -> a / Double 2) -- | @fo epsilon = -epsilon * cot (epsilon * pi / 2)@ fo :: Double -> Double fo :: Double -> Double fo Double epsilon = -Double epsilon Double -> Double -> Double forall a. Num a => a -> a -> a * Double -> Double cot (Double epsilon Double -> Double -> Double forall a. Num a => a -> a -> a * Double forall a. Floating a => a pi Double -> Double -> Double forall a. Fractional a => a -> a -> a / Double 2) -- | @g nu epsilon = sqrt (nu ** 2 - epsilon ** 2)@ g :: Double -> Double -> Double g :: Double -> Double -> Double g Double nu Double epsilon = Double -> Double forall a. Floating a => a -> a sqrt (Double nu Double -> Double -> Double forall a. Floating a => a -> a -> a ** Double 2 Double -> Double -> Double forall a. Num a => a -> a -> a - Double epsilon Double -> Double -> Double forall a. Floating a => a -> a -> a ** Double 2) ------------------ -- * Exercise 3.9 ------------------ -- $ex39 -- __How many functions with type @Bool -> Bool@ are there?__ -- -- /There are 4 @Bool -> Bool@ functions./ -- -- __What would be good names for them?__ -- -- /@alwaysFalse@, @alwaysTrue@, 'identity', and 'not'/ -- -- __How many functions have type @Bool -> Bool -> Bool@?__ -- -- /There are 16 @Bool -> Bool -> Bool@ functions./ -- -- Source: [The 16 Boolean Logic Functions of Two-Input Systems](https://www.allaboutcircuits.com/technical-articles/16-boolean-logic-functions-of-2-input-system/) ------------------ -- * Exercise 3.10 ------------------ -- $ex310 -- > True || False && False