Skip to content

Update my stuff plz #20

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Homework/Homework01/Homework01.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,25 @@
-- Question 1
-- Write a multiline comment below.

{- This is a multi-
line comment -}

-- Question 2
-- Define a function that takes a value and multiplies it by 3.

timesThree x = x * 3

-- Question 3
-- Define a function that calculates the area of a circle.

areaOfCircle rad = pi * x^2

-- Question 4
-- Define a function that calculates the volume of a cylinder by composing the previous function together with the height of the cylinder.

volumeOfCylinder rad height = areaOfCircle rad * height

-- Question 5
-- Define a function that takes the height and radius of a cylinder and checks if the volume is greater than or equal to 42.

checkVolume rad height = volumeOfCylinder rad height > 42
48 changes: 43 additions & 5 deletions Homework/Homework02/Homework02.hs
Original file line number Diff line number Diff line change
@@ -1,33 +1,71 @@

-- Question 1
-- Add the type signatures for the functions below and then remove the comments and try to compile.
-- (Use the types presented in the lecture.)

-- f1 x y z = x ** (y/z)
f1 :: Float -> Float -> Float -> Float
f1 x y z = x ** (y/z)

-- f2 x y z = sqrt (x/y - z)
f2 :: Double -> Double -> Double -> Double
f2 x y z = sqrt (x/y - z)

-- f3 x y = [x == True] ++ [y]
f3 :: Bool -> Bool -> [Bool]
f3 x y = [x == True] ++ [y]

-- f4 x y z = x == (y ++ z)
f4 :: String -> String -> String -> Bool
f4 x y z = x == (y ++ z)


-- Question 2
-- Are really all variables in Haskell immutable? Try googling for the answer.

{-Although the functional programming paradigm emphasises the virtues of immutable variables, sometimes you need mutable variables nonetheless.
You can either simulate mutable variables using the state monad provided for instance by Control.Monad.Trans.State in the transformers package
or you can use really mutable variables as provided by Data.IORef or Data.STRef or Control.Concurrent.STM.TVar from the stm package.
In either case you need a monad in order to cope with mutability, while staying purely functional. -}

-- Question 3
-- Why should we define type signatures of functions? How can they help you? How can they help others?

{- Signatures cast the data types for the function output and it's associated inputs.
This helps me by allowing me to restrict the data types of the input and output of my functions. For instance, I may want to restrict a function to useing Int instead of Integer for computational efficiency.
This helps others by allowing them to read my code and understand what data types are assocaited with my functions -}

-- Question 4
-- Why should you define type signatures for variables? How can they help you?

{- I would define type signatures for variables to assign the data type to the variable.
Since variables can be changed it is important to assign the data type to limit what data the variable can carry.
It is important that data types of variables match the signature of a function, also important when appending/prepending variables to lists or Tuples -}

-- Question 5
-- Are there any functions in Haskell that let you transform one type to the other? Try googling for the answer.

{- convert f x y = fromIntegral (f (fromIntegral x) (fromIntegral y))

This is pretty straightforward. However, if I were to do it, I'd take advantage of the on function from Data.Function, which converts the inputs of functions that take two arguments before applying it.
So, in your example, it would look like this:

convert f x y = fromIntegral ((f `on` fromIntegral) x y)

I, personally, would go one step further and make this function point-free, but because on f fromIntegral expects two arguments, you can't just use (.), so I usually define an operator for this:

(.:) = (.) . (.)

You can figure out why this works on your own if you'd like, but now I can define convert as this:

convert f = fromIntegral .: (f `on` fromIntegral)

I feel that this is a lot more readable, but I am biased because I have been coding Haskell like this for a while now.

Also, if you look at the inferred type of this variable, you'd see that it's much more general than what you wanted:

convert :: (Integral a, Integral a1, Num b, Num b1) = (b1 -> b1 -> a) -> a1 -> a1 -> b -}


-- Question 6
-- Can you also define in Haskell list of lists? Did we showed any example of that? How would you access the inner
-- most elements?

{- Lists can be concatinated in Haskell, but as far as I am aware a list cannot be an element of a list. I get an error when I try to insert a list as an element of a new list.
No examples were shown of defining lists of lists.
To access the inner elements of a list I would use the function "!!" along with the element number (starting from 0) I want to access -}
42 changes: 42 additions & 0 deletions Homework/Homework03/Homework03.hs
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import Text.XHtml.Transitional (maxlength)
import Distribution.Simple.Utils (xargs)
-- Question 1
-- Write a function that checks if the monthly consumption of an electrical device is bigger, equal, or smaller than the maximum allowed and
-- returns a message accordingly.
-- The function has to take the hourly consumption of an electrical device, the hours of daily use, and the maximum monthly consumption allowed.
-- (Monthly usage = consumption (kW) * hours of daily use (h) * 30 days).

checkConsumption :: Float -> Float -> Float -> String
checkConsumption use hrs maxCon
| consumption < maxCon = "Usage within limits."
| consumption == maxCon = "Usage at limit."
| otherwise = "Usage exceeds limits."
where
consumption = use * hrs * 30

-- Question 2
-- Prelude:
Expand All @@ -12,19 +21,52 @@

-- In the previous function, return the excess/savings of consumption as part of the message.

checkConsumption2 :: Float -> Float -> Float -> String
checkConsumption2 use hrs maxCon
| consumption < maxCon = "Usage within limits with " ++ show remainder ++ " kW remaining."
| consumption == maxCon = "Usage at limit " ++ show remainder ++ " kW remaining."
| otherwise = "Usage exceeds limits " ++ show remainder ++ " kW remaining."
where
consumption = use * hrs * 30
remainder = maxCon - consumption


-- Question 3
-- Write a function that showcases the advantages of using let expressions to split a big expression into smaller ones.
-- Then, share it with other students in Canvas.

showCaseLet :: Float -> Float
showCaseLet x =
let funk1 x = x + 3
funk2 x = -x + 9
in if x <=3 then funk1 x else funk2 x

-- Question 4
-- Write a function that takes in two numbers and returns their quotient such that it is not greater than 1.
-- Return the number as a string, and in case the divisor is 0, return a message why the division is not
-- possible. To implement this function using both guards and if-then-else statements.

returnQuotient :: Float -> Float -> String
returnQuotient x y
| x > y = if x /= 0 then "Route 1a: " ++ show(x/y) else "Route 1b: x is larger but equal to zero"
| x < y = if y /= 0 then "Route 2a: " ++ show(y/x) else "Route 2b: y is larger but equal to zero"
| otherwise = if x /=0 then "Route 3a: 1" else "Route 3b: x and y are both zero"

-- Back of the book answer
guardsAndIf :: Double -> Double -> String
guardsAndIf a b
| a > b = if a /= 0 then show(a/b) else "a is larger but 0"
| a < b = if b /= 0 then show(b/a) else "b is larger but 0"
| otherwise = if a /= 0 then "1" else "a and b are both 0"

-- Question 5
-- Write a function that takes in two numbers and calculates the sum of squares for the product and quotient
-- of those numbers. Write the function such that you use a where block inside a let expression and a
-- let expression inside a where block.

--I have a question regarding question #5. It asks to calculates the sum of squares for the product and quotient of 2 numbers. Just wondering what the equation for this, given x and y as inputs, is: (x + y)^2 + (x / y)^2?

funky :: Float -> Float -> Float
funky x y = let sqrtProd = sqrt xTimesY where xTimesY = x * y
in sqrtProd + sqrtQuot
where sqrtQuot = let xDivY = x / y in sqrt xDivY
28 changes: 28 additions & 0 deletions Homework/Homework04/Homework04.hs
Original file line number Diff line number Diff line change
@@ -1,30 +1,58 @@
import Distribution.Simple.Utils (xargs)
-- Question 1
-- Lets say you have the nested values defined bellow. How would you get the value of
-- 4 by using only pattern matching in a function?

nested :: [([Int], [Int])]
nested = [([1,2],[3,4]), ([5,6],[7,8])]

firstElement = nested !! 0

fourthElement :: (x, y) -> y
fourthElement (_,y) = y

three :: [([Int], [Int])] -> Int
three [(_,[_,d]), _] = d
three _ = 0

-- Question 2
-- Write a function that takes a list of elements of any type and, if the list has 3 or more elements, it
-- removes them. Else, it does nothing. Do it two times, one with multiple function definitions and one with
-- case expressions.

removeElements :: [a] -> [a]
removeElements newList
| [x,y] = [x,y]
| [x,y,z] = []
| [x,y,z,a] = [a]

-- Question 3
-- Create a function that takes a 3-element tuple (all of type Integer) and adds them together

addThreeIntegers :: (Int, Int, Int) -> Int
addThreeIntegers (x, y, z) = x + y + z


-- Question 4
-- Implement a function that returns True if a list is empty and False otherwise.

findEmptyList :: [a] -> Bool
findEmptyList [] = True
findEmptyList _ = False

-- Question 5
-- Write the implementation of the tail function using pattern matching. But, instead of failing if
-- the list is empty, return an empty list.

tailFunction :: [a] -> [a]
tailFunction (x:xs) = xs
tailFunction [] = []

-- Question 6
-- write a case expression wrapped in a function that takes an Int and adds one if it's even. Otherwise does nothing.
-- (Use the `even` function to check if the number is even.)

makeOdd :: Int -> Int
makeOdd x = case even x of
True -> x + 1
False -> x