zhaw-fup/Exercises/exercise-1/Code/A_BasicsTodo.hs

233 lines
4.8 KiB
Haskell
Raw Normal View History

2024-03-14 13:59:07 +00:00
{- Contents
A short introduction to Haskell;
The very basics
-}
-----------------------------------------------------------
-- Comments
-----------------------------------------------------------
-- a single line comment
{- a multiline comment
{- can be nested -}
-}
{- Usually (from now on), we will try to adhere to the
following conventuion/structure for multiline comments:
-}
{- Optional "title" of the comment
Content of the comment possibly spaning multiple lines
with length <= 60.
-}
-----------------------------------------------------------
-- Simple declarations
-----------------------------------------------------------
{- Declaring a variable
Generally, in Haskell we define the type of a variable
in a separate line before we define the variable.
-}
-- 'five' is the integer 5
five :: Integer
five = 5
{-
'six' is the integer 6. The type 'Integer' can
accomodate integers of arbitrary size
-}
six :: Integer
six = 6
-- 'four' is the float 4.0
four :: Float
four = 4
-----------------------------------------------------------
---- Numeric operations
-----------------------------------------------------------
seven :: Integer
seven = five + 2
theIntEight :: Integer
theIntEight = 3 + five
theFloatSeven :: Float
theFloatSeven = 3 + four
twentyFour :: Float
twentyFour = 3 * 2 ^ 3
{- Integer division
'div' denotes integer division. Generally, it is
possible to write a function between '`' to use infix
notation. I order to define functions that are
"natively" infix, you would use brackets '(...)' when
defining the function/operator.
-}
intSevenByThree :: Integer
intSevenByThree = seven `div` 3
{- Division
The "normal" division '/' is for "fractional numbers,
e.g. floats.
-}
floatSevenByThree :: Float
floatSevenByThree = 7 / 3
{- Exercise
Fill out the types where possible
Check your solutions with the REPL.
2024-03-14 14:56:10 +00:00
>>> x :: Integer = 2 ^ 3
2024-03-14 13:59:07 +00:00
2024-03-14 14:56:10 +00:00
>>> y :: Float = 2.0 ^ 3
2024-03-14 13:59:07 +00:00
2024-03-14 14:56:10 +00:00
>>> a :: Integer = x + 5
2024-03-14 13:59:07 +00:00
2024-03-14 14:56:10 +00:00
b :: Float
>>> b = y/2
>>> :t b
b :: Float
2024-03-14 13:59:07 +00:00
2024-03-14 14:56:10 +00:00
c :: Error
>>> c = y `div` 3
>>> :t c
No instance for (Integral Float) arising from a use of `div'
In the expression: y `div` 3
In an equation for `c': c = y `div` 3
2024-03-14 13:59:07 +00:00
-}
-----------------------------------------------------------
---- Booleans and boolean operations
-----------------------------------------------------------
true :: Bool
true = True
false :: Bool
false = False
alsoTrue :: Bool
alsoTrue = true || false
alsoFalse :: Bool
alsoFalse = true && false
moreTruth :: Bool
moreTruth = not alsoFalse
-----------------------------------------------------------
---- Strings and chars
-----------------------------------------------------------
aChar :: Char
aChar = 'a'
aString :: String
aString = "Happy new year"
greeting :: String
greeting = aString ++ " " ++ "2022"
greeting2 :: String
greeting2 = concat
[ aString
, " "
, "2022"
]
{- Warning
The operators are strongly typed; they can only digest
values of the same type. The following declarations are
thus rejected by the type checker:
aString = "Happy new year"
greeting = aString ++ " " ++ 2022
five :: Int
five = 5
seven = five + 2.0
-}
-----------------------------------------------------------
---- Lists
-----------------------------------------------------------
{-
We will often use `List` (linked lists), a generic
container to hold multiple values of *the same type*.
-}
aListOfStrings :: [String]
aListOfStrings = [ "one", "two", "three" ]
aListOfInts :: [Integer]
aListOfInts = [ 1, 2, 3 ]
{- Exercise
Fill out the type, check your solutions with the REPL.
2024-03-14 14:56:10 +00:00
friendGroups :: [[String]]
2024-03-14 13:59:07 +00:00
friendGroups =
[ ["Peter", "Anna", "Roman", "Laura"]
, ["Anna","Reto"]
, ["Christoph", "Mara", "Andrew"]
]
-}
{- List comprehension
Aside from declaring lists explicitly by writing down
their element (as shown before), lists can also be
declared by "list comprehension" and also as "ranges".
-}
someInts :: [Integer]
someInts = [1..15] -- range
someEvens :: [Integer]
someEvens = [ 2*x | x <- [-5..5]]
pairs :: [(Integer, Bool)]
pairs = [ (x,y) | x <- [0..5], y <- [True, False]]
lessThanPairs :: [(Integer,Integer)]
lessThanPairs = [ (x,y)
| x <- [0..5]
, y <- [0..5]
, x < y -- guard
, x > 1 -- second guard
]
{- Exercise
Use list comprehension to declare a list that contains
all square numbers between 1 and 100.
-}
squares :: [Integer]
2024-03-14 14:56:10 +00:00
squares = [ x^2 | x <- [1..(floor (sqrt 100))]]
-- >>> squares
-- [1,4,9,16,25,36,49,64,81,100]
2024-03-14 13:59:07 +00:00
{- Exercise
Use list comprehension to declare a list that contains
all odd square numbers between 1 and 100.
-}
oddSquares :: [Integer]
2024-03-14 14:56:10 +00:00
oddSquares = [ x^2 | x <- [1..(floor (sqrt 100))], odd (x^2)]
-- >>> oddSquares
-- [1,9,25,49,81]