- Questions & Answers
- Accounting
- Computer Science
- Automata or Computationing
- Computer Architecture
- Computer Graphics and Multimedia Applications
- Computer Network Security
- Data Structures
- Database Management System
- Design and Analysis of Algorithms
- Information Technology
- Linux Environment
- Networking
- Operating System
- Software Engineering
- Big Data
- Android
- iOS
- Matlab

- Economics
- Engineering
- Finance
- Thesis
- Management
- Science/Math
- Statistics
- Writing
- Dissertations
- Essays
- Programming
- Healthcare
- Law

- Log in | Sign up

03-types-and-typeclasses

February 20, 2021

1 Types and Typeclasses

1.1 Believe the type

1.1.1 Static type system

Haskell has a static type system.

• The type of every expression is known at compile time, which leads to safer code.

• If you write a program where you try to divide a boolean type with some number, it won’t

even compile.

• That’s good because it’s better to catch such errors at compile time instead of having your

program crash.

• Everything in Haskell has a type, so the compiler can reason quite a lot about your program

before compiling it.

1.1.2 Type inference

Unlike Java or Pascal, Haskell has type inference.

• It can infer that on its own, so we don’t have to explicitly write out the types of our functions

and expressions to get things done.

Understanding the type system is a very important part of learning Haskell.

• A type is a kind of label that every expression has.

• It tells us in which category of things that expression fits.

• The expression True is a boolean, "hello" is a string, etc.

Jupyter Note: We’ll turn off the automatic linting for IHaskell first.

[1]: :opt no-lint

1.1.3 Examine the types of some expressions

We’ll do that by using the :t command which, followed by any valid expression, tells us its type.

[2]: :t 'a'

'a' :: Char

[3]: :t True

1

https://hackage.haskell.org/package/base/docs/Prelude.html#v:True

https://github.com/gibiansky/IHaskell/wiki#opt-no-lint

True :: Bool

[4]: :t "HELLO!"

"HELLO!" :: [Char]

[5]: :t (True, 'a')

(True, 'a') :: (Bool, Char)

[6]: :t 4 == 5

4 == 5 :: Bool

1.1.4 Types

Expression Types

• :: is read as “has type of”.

• Explicit types are always denoted with the first letter in capital case.

– 'a', as it would seem, has a type of Char, which stands for character.

– True is of a Bool type.

– Examining the type of "HELLO!" yields a [Char]. The square brackets denote a list.

• Unlike lists, each tuple length has its own type.

– So the expression of (True, 'a') has a type of (Bool, Char),

– an expression such as ('a','b','c') would have the type of (Char, Char, Char).

• 4 == 5 will always return False, so its type is Bool.

Function Types

• Functions also have types.

• When writing our own functions, we can choose to give them an explicit type declaration.

• From here on, we’ll give all the functions that we make type declarations.

[7]: removeNonUppercase :: [Char] -> [Char]

removeNonUppercase st = [ c | c <- st, c `elem` ['A'..'Z'] ]

removeNonUppercase "abc123AGC"

"AGC"

• removeNonUppercase has a type of [Char] -> [Char], meaning that it maps from a string

to a string.

• It takes one string as a parameter and returns another as a result.

• The [Char] type is synonymous with String so it’s clearer if we write removeNonUppercase

:: String -> String.

• We didn’t have to give this function a type declaration because the compiler can infer by

itself that it’s a function from a string to a string but we did anyway.

Function with multiple parameters But how do we write out the type of a function that

takes several parameters?

2

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Char

https://hackage.haskell.org/package/base/docs/Prelude.html#v:True

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bool

https://hackage.haskell.org/package/base/docs/Prelude.html#v:False

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bool

https://hackage.haskell.org/package/base/docs/Prelude.html#t:String

[8]: addThree :: Int -> Int -> Int -> Int

-- addThree :: Int, Int, Int -> Int -- wrong

addThree x y z = x + y + z

[9]: addThree 1 2 3

6

[10]: addTreeFortwo = addThree 1

[11]: addTreeFortwo 2 3

6

[12]: :t (+)

(+) :: forall a. Num a => a -> a -> a

• The parameters are separated with -> and there’s no special distinction between the param-

eters and the return type.

• The return type is the last item in the declaration and the parameters are the first three.

Check funtion types If you want to give your function a type declaration but are unsure as to

what it should be, * Functions are expressions too, so :t works on them without a problem.

[13]: :t take

take :: forall a. Int -> [a] -> [a]

[14]: take 2 [1..10]

[1,2]

1.1.5 Common types

Here’s an overview of some common types.

Int

• Int stands for integer.

– It’s used for whole numbers. 7 can be an Int but 7.2 cannot.

– Int is bounded, which means that it has a minimum and a maximum value. Usually

on 32-bit machines the maximum possible Int is XXXXXXXXXXand the minimum is -

XXXXXXXXXX.

• Integer stands for also integer.

– The main difference is that it’s not bounded so it can be used to represent really really

big numbers.

– Int, however, is more efficient.

[15]: factorial :: Integer -> Integer

factorial n = product [1..n] -- 1*2*3*..*n

3

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Int

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Int

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Int

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Int

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Integer

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Int

[16]: factorial 50

304140932017133780436126081660647688443776415 XXXXXXXXXX

Float Float is a real floating point with single precision.

[17]: circumference :: Float -> Float

circumference r = 2 * pi * r

[18]: circumference 4.0

XXXXXXXXXX

Double Double is a real floating point with double the precision!

[19]: circumference' :: Double -> Double

circumference' r = 2 * pi * r

[20]: circumference' 4.0

XXXXXXXXXX

Bool Bool is a boolean type. It can have only two values: True and False.

Char Char represents a character. It’s denoted by single quotes. A list of characters is a string.

Tuple

• Tuples are types but they are dependent on their length as well as the types of their compo-

nents,

• so there is theoretically an infinite number of tuple types.

• Note that the empty tuple () is also a type which can only have a single value: ()

[21]: :t (12,'a',"a",[1..2], [[1],[2]])

(12,'a',"a",[1..2], [[1],[2]]) :: forall a1 a2 a3. (Enum a1, Num a2, Num a1, Num␣

↪→a3) => (a2, Char, [Char], [a1], [[a3]])

1.2 Type variables

Because head takes a list of any type and returns the first element, so what could it be?

[22]: fun :: (Integral a) => a -> a-> a -> [a]

fun x y z = [x,y,z]

[23]: fun 1 2 3

[1,2,3]

[24]: -- fun :: (Int a) => a -> a-> a -> [a] -- wrong

fun x y z = [x,y,z]

4

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Float

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Double

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bool

https://hackage.haskell.org/package/base/docs/Prelude.html#v:True

https://hackage.haskell.org/package/base/docs/Prelude.html#v:False

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Char

https://hackage.haskell.org/package/base/docs/Prelude.html#v:head

1.2.1 Type variable

Hmmm! What is this a? Is it a type?

• types are written in capital case, so it can’t exactly be a type.

• it’s actually a type variable. That means that a can be of any type.

• This is much like generics in other languages, only in Haskell it’s much more powerful because

it allows us to easily write very general functions if they don’t use any specific behavior of

the types.

• Functions that have type variables are called polymorphic functions.

1.2.2 Type variable examples

Although type variables can have names longer than one character, we usually give them names of

a, b, c, d …

The type declaration of head states that it takes a list of any type and returns one element of that

type.

[25]: :t head

head :: forall a. [a] -> a

[26]: :t fst

fst :: forall a b. (a, b) -> a

• fst takes a tuple which contains two types and returns an element which is of the same type

as the pair’s first component.

• That’s why we can use fst on a pair that contains any two types.

• Note that just because a and b are different type variables, they don’t have to be different

types. It just states that the first component’s type and the return value’s type are the same.

1.3 Typeclasses 101

• A typeclass is a sort of interface that defines some behavior.

• If a type is a part of a typeclass, that means that it supports and implements the behavior

the typeclass describes.

• Typeclasses are NOT like classes in object oriented languages. They are like Java interfaces.

1.3.1 Eq typeclass

What’s the type signature of the == function?

[27]: :t (==)

(==) :: forall a. Eq a => a -> a -> Bool

[28]: (==) 2 3

False

[29]: XXXXXXXXXX

5

https://hackage.haskell.org/package/base/docs/Prelude.html#v:head

https://hackage.haskell.org/package/base/docs/Prelude.html#v:fst

https://hackage.haskell.org/package/base/docs/Prelude.html#v:fst

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-61--61-

5

Note:

• the equality operator, == is a function.

• So are +, *, -, / and pretty much all operators.

• If a function is comprised only of special characters, it’s considered an infix function by

default.

• If we want to examine its type, pass it to another function or call it as a prefix function, we

have to surround it in parentheses.

[30]: :t (==)

(==) :: forall a. Eq a => a -> a -> Bool

• Everything before the => symbol is called a class constraint.

• It reads like this: the equality function takes any two values that are of the same type and

returns a Bool. ### Eq typeclass cont’ed

• The type of those two values must be a member of the Eq class (this was the class constraint).

• The Eq typeclass provides an interface for testing for equality.

• Any type where it makes sense to test for equality between two values of that type should be

a member of the Eq class.

• All standard Haskell types except for IO (the type for dealing with input and output) and

functions are a part of the Eq typeclass.

• The elem function has a type of (Eq a) => a -> [a] -> Bool because it uses == over a list

to check whether some value we’re looking for is in it.

1.3.2 Some basic typeclasses

Eq

• Eq is used for types that support equality testing.

• The functions its members implement are == and /=.

• So if there’s an Eq class constraint for a type variable in a function, it uses == or /= somewhere

inside its definition.

• All the types we mentioned previously except for functions are part of Eq, so they can be

tested for equality.

[31]: 5 == 5

True

[32]: 5 /= 5 -- 5 \= 5

False

[33]: 'a' == 'a'

True

[34]: "Ho Ho" == "Ho Ho"

True

6

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-61--61-

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-43-

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-42-

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-45-

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-47-

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bool

https://hackage.haskell.org/package/base/docs/Prelude.html#t:IO

https://hackage.haskell.org/package/base/docs/Prelude.html#v:elem

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-61--61-

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-61--61-

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-47--61-

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-61--61-

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-47--61-

[35]: 3.432 == 3.432

True

Ord Ord is for types that have an ordering.

[36]: :t (>)

(>) :: forall a. Ord a => a -> a -> Bool

• All the types we covered so far except for functions are part of Ord.

• Ord covers all the standard comparing functions such as >, <, >= and <=.

• The compare function takes two Ord members of the same type and returns an ordering.

• Ordering is a type that can be GT, LT or EQ, meaning greater than, lesser than and equal,

respectively.

• To be a member of Ord, a type must first have membership in the prestigious and exclusive

Eq club.

[37]: "Abrakadabra" < "Zebra"

True

[38]: "Abrakadabra" `compare` "Zebra"

:t compare

LT

compare :: forall a. Ord a => a -> a -> Ordering

[39]: 5 >= 2

True

[40]: 5 `compare` 3

GT

Show

• Members of Show can be presented as strings.

• All types covered so far except for functions are a part of Show.

• The most used function that deals with the Show typeclass is show. It takes a value whose

type is a member of Show and presents it to us as a string.

[41]: output = "The output is: " ++ show 3

output

"The output is: 3"

[42]: show 5.334

7

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Ord

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Ord

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Ord

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-62-

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-60-

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-62--61-

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-60--61-

https://hackage.haskell.org/package/base/docs/Prelude.html#v:compare

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Ord

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Ordering

https://hackage.haskell.org/package/base/docs/Prelude.html#v:GT

https://hackage.haskell.org/package/base/docs/Prelude.html#v:LT

https://hackage.haskell.org/package/base/docs/Prelude.html#v:EQ

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Ord

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Show

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Show

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Show

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Show

"5.334"

[43]: show True

"True"

Read

• Read is sort of the opposite typeclass of Show.

• The read function takes a string and returns a type which is a member of Read.

[44]: read "True" || False

True

[45]: read "8.2" + 3.8

12.0

[46]: read "5" - 2

3

[47]: read "[1,2,3,4]" ++ [3]

[1,2,3,4,3]

But what happens if we try to do just read "4"?

[48]: read "5"

Prelude.read: no parse

The complete error messages: :1:0: Ambiguous type variable a' in the constraint:Read a’

arising from a use of ‘read’ at :1:0-7 Probable fix: add a type signature that fixes these type

variable(s)

• What GHC is telling us here is that it doesn’t know what we want in return.

Let’s take a look at the type signature of read.

[49]: :t read

read :: forall a. Read a => String -> a

It returns a type that’s part of Read but if we don’t try to use it in some way later, it has no way

of knowing which type.

• In the previous uses of read we did something with the result afterwards. That way, GHC

could infer what kind of result we wanted out of our read. If we used it as a boolean, it knew

it had to return a Bool.

• But now, it knows we want some type that is part of the Read class, it just doesn’t know

which one.

8

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Read

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Show

https://hackage.haskell.org/package/base/docs/Prelude.html#v:read

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Read

https://hackage.haskell.org/package/base/docs/Prelude.html#v:read

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Read

https://hackage.haskell.org/package/base/docs/Prelude.html#v:read

https://hackage.haskell.org/package/base/docs/Prelude.html#v:read

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bool

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Read

Explicit type annotation We can use explicit type annotations.

• Type annotations are a way of explicitly saying what the type of an expression should be.

• We do that by adding :: at the end of the expression and then specifying a type. Observe:

[50]: read "5" :: Int

5

[51]: read "5" :: Float

5.0

[52]: read "5" * 4

20

[53]: read "[1,2,3,4]" :: [Int]

[1,2,3,4]

[54]: read "(3, 'a')" :: (Int, Char)

(3,'a')

• Most expressions are such that the compiler can infer what their type is by itself.

• But sometimes, the compiler doesn’t know whether to return a value of type Int or Float

for an expression like read "5".

• To see what the type is, Haskell would have to actually evaluate read "5".

• Haskell is a statically typed language, it has to know all the types before the code is compiled

(or in the case of GHCI, evaluated).

Enum

• Enum members are sequentially ordered types — they can be enumerated.

• The main advantage of the Enum typeclass is that we can use its types in list ranges.

• They also have defined successors and predecessors, which you can get with the

– succ and

– pred functions.

• Types in this class: (), Bool, Char, Ordering, Int, Integer, Float and Double.

[55]: ['a'..'e']

"abcde"

[56]: [LT .. GT]

[LT,EQ,GT]

[57]: [3 .. 5]

[3,4,5]

9

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Int

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Float

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Enum

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Enum

https://hackage.haskell.org/package/base/docs/Prelude.html#v:succ

https://hackage.haskell.org/package/base/docs/Prelude.html#v:pred

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bool

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Char

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Ordering

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Int

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Integer

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Float

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Double

[58]: succ 'B'

'C'

Bounded Bounded members have an upper and a lower bound.

Jupyter Note: Parentheses resolve ambiguity in the following expressions, see IHaskell

Issue #509 The type signature for ‘minBound’ lacks an accompanying binding

[59]: (minBound :: Int)

XXXXXXXXXX

[60]: (maxBound :: Char)

' XXXXXXXXXX'

[61]: (maxBound :: Bool)

True

[62]: (minBound :: Bool)

False

• minBound and maxBound are interesting because they have a type of (Bounded a) => a. In

a sense they are polymorphic constants.

• All tuples are also part of Bounded if the components are also in it.

[63]: (maxBound :: (Bool, Int, Char))

(True, XXXXXXXXXX,' XXXXXXXXXX')

Num

• Num is a numeric typeclass.

• Its members have the property of being able to act like numbers.

[64]: :t 20

20 :: forall p. Num p => p

• It appears that whole numbers are also polymorphic constants.

• They can act like any type that’s a member of the Num typeclass.

[65]: 20 :: Int

20

[66]: 20 :: Integer

20

10

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bounded

https://github.com/gibiansky/IHaskell/issues/509

https://github.com/gibiansky/IHaskell/issues/509

https://hackage.haskell.org/package/base/docs/Prelude.html#v:minBound

https://hackage.haskell.org/package/base/docs/Prelude.html#v:maxBound

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bounded

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Num

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Num

[67]: 20 :: Float

20.0

[68]: 20 :: Double

20.0

[69]: 20.0 :: Int

:1:1: error:

• No instance for (Fractional Int) arising from the literal ‘20.0’

• In the expression: 20.0 :: Int

In an equation for ‘it’: it = 20.0 :: Int

[70]: :i Num

Integral Integral is also a numeric typeclass.

• Num includes all numbers,including real numbers and integral numbers,

• Integral includes only integral (whole) numbers.

• In this typeclass are Int and Integer.

Floating Floating includes only floating point numbers, so Float and Double.

1.3.3 Number conversions

fromIntegral A very useful function for dealing with numbers is fromIntegral. fromIntegral

:: (Num b, Integral a) => a -> b.

• It takes an integral number and turns it into a more general number.

• For instance, the length function has a type declaration of length :: [a] -> Int instead

of having a more general type of (Num b) => length :: [a] -> b.

• If we try to get a length of a list and then add it to 3.2, we’ll get an error because we tried

to add together an Int and a floating point number.

[71]: XXXXXXXXXX

7.2

[72]: :t length

length :: forall (t :: * -> *) a. Foldable t => t a -> Int

[73]: length [1,2,3,4] + 3.2

:1:20: error:

• No instance for (Fractional Int) arising from the literal ‘3.2’

• In the second argument of ‘(+)’, namely ‘3.2’

11

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Integral

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Num

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Integral

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Int

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Integer

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Floating

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Float

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Double

https://hackage.haskell.org/package/base/docs/Prelude.html#v:fromIntegral

https://hackage.haskell.org/package/base/docs/Prelude.html#v:length

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Int

In the expression: length [1, 2, 3, 4] + 3.2

In an equation for ‘it’: it = length [1, 2, 3, …] + 3.2

[74]: fromIntegral(length [1,2,3,4]) + 3.2

7.2

Example: * If we examine the type of *, we’ll see that it accepts all numbers.

[75]: :t (*)

4 * 3.4

(*) :: forall a. Num a => a -> a -> a

13.6

• It takes two numbers of the same type and returns a number of that type.

• That’s why (5 :: Int) * (6 :: Integer) will result in a type error

• whereas 5 * (6 :: Integer) will work just fine and produce an Integer because 5 can act

like an Integer or an Int.

• To join Num, a type must already be friends with Show and Eq.

1.4 Summary

• Types: Int/Integer, Float, Double, Bool, Char, Tuple

• Typeclasses: Eq, Ord, Show, Read, Enum, Bounded, Num, Integral, Floating

• Type conversion: fromIntegral, fromRational/toRational, truncate/round/ceiling/floor

• Function declaration

– foo:: a -> a

– foo:: Int -> Float

– foo:: a -> a -> a -> a

– foo:: (Ord a) => a -> b -> c -> a

– foo:: (Integral a) => a -> Int -> a

[76]: foo:: a -> a

foo a = a

:t foo

foo :: forall a. a -> a

[77]: foo:: a -> Int -> a

foo x y = x

12

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-42-

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Integer

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Integer

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Int

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Num

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Show

Types and Typeclasses

Believe the type

Static type system

Type inference

Examine the types of some expressions

Types

Common types

Type variables

Type variable

Type variable examples

Typeclasses 101

Eq typeclass

Some basic typeclasses

Number conversions

Summary

February 20, 2021

1 Types and Typeclasses

1.1 Believe the type

1.1.1 Static type system

Haskell has a static type system.

• The type of every expression is known at compile time, which leads to safer code.

• If you write a program where you try to divide a boolean type with some number, it won’t

even compile.

• That’s good because it’s better to catch such errors at compile time instead of having your

program crash.

• Everything in Haskell has a type, so the compiler can reason quite a lot about your program

before compiling it.

1.1.2 Type inference

Unlike Java or Pascal, Haskell has type inference.

• It can infer that on its own, so we don’t have to explicitly write out the types of our functions

and expressions to get things done.

Understanding the type system is a very important part of learning Haskell.

• A type is a kind of label that every expression has.

• It tells us in which category of things that expression fits.

• The expression True is a boolean, "hello" is a string, etc.

Jupyter Note: We’ll turn off the automatic linting for IHaskell first.

[1]: :opt no-lint

1.1.3 Examine the types of some expressions

We’ll do that by using the :t command which, followed by any valid expression, tells us its type.

[2]: :t 'a'

'a' :: Char

[3]: :t True

1

https://hackage.haskell.org/package/base/docs/Prelude.html#v:True

https://github.com/gibiansky/IHaskell/wiki#opt-no-lint

True :: Bool

[4]: :t "HELLO!"

"HELLO!" :: [Char]

[5]: :t (True, 'a')

(True, 'a') :: (Bool, Char)

[6]: :t 4 == 5

4 == 5 :: Bool

1.1.4 Types

Expression Types

• :: is read as “has type of”.

• Explicit types are always denoted with the first letter in capital case.

– 'a', as it would seem, has a type of Char, which stands for character.

– True is of a Bool type.

– Examining the type of "HELLO!" yields a [Char]. The square brackets denote a list.

• Unlike lists, each tuple length has its own type.

– So the expression of (True, 'a') has a type of (Bool, Char),

– an expression such as ('a','b','c') would have the type of (Char, Char, Char).

• 4 == 5 will always return False, so its type is Bool.

Function Types

• Functions also have types.

• When writing our own functions, we can choose to give them an explicit type declaration.

• From here on, we’ll give all the functions that we make type declarations.

[7]: removeNonUppercase :: [Char] -> [Char]

removeNonUppercase st = [ c | c <- st, c `elem` ['A'..'Z'] ]

removeNonUppercase "abc123AGC"

"AGC"

• removeNonUppercase has a type of [Char] -> [Char], meaning that it maps from a string

to a string.

• It takes one string as a parameter and returns another as a result.

• The [Char] type is synonymous with String so it’s clearer if we write removeNonUppercase

:: String -> String.

• We didn’t have to give this function a type declaration because the compiler can infer by

itself that it’s a function from a string to a string but we did anyway.

Function with multiple parameters But how do we write out the type of a function that

takes several parameters?

2

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Char

https://hackage.haskell.org/package/base/docs/Prelude.html#v:True

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bool

https://hackage.haskell.org/package/base/docs/Prelude.html#v:False

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bool

https://hackage.haskell.org/package/base/docs/Prelude.html#t:String

[8]: addThree :: Int -> Int -> Int -> Int

-- addThree :: Int, Int, Int -> Int -- wrong

addThree x y z = x + y + z

[9]: addThree 1 2 3

6

[10]: addTreeFortwo = addThree 1

[11]: addTreeFortwo 2 3

6

[12]: :t (+)

(+) :: forall a. Num a => a -> a -> a

• The parameters are separated with -> and there’s no special distinction between the param-

eters and the return type.

• The return type is the last item in the declaration and the parameters are the first three.

Check funtion types If you want to give your function a type declaration but are unsure as to

what it should be, * Functions are expressions too, so :t works on them without a problem.

[13]: :t take

take :: forall a. Int -> [a] -> [a]

[14]: take 2 [1..10]

[1,2]

1.1.5 Common types

Here’s an overview of some common types.

Int

• Int stands for integer.

– It’s used for whole numbers. 7 can be an Int but 7.2 cannot.

– Int is bounded, which means that it has a minimum and a maximum value. Usually

on 32-bit machines the maximum possible Int is XXXXXXXXXXand the minimum is -

XXXXXXXXXX.

• Integer stands for also integer.

– The main difference is that it’s not bounded so it can be used to represent really really

big numbers.

– Int, however, is more efficient.

[15]: factorial :: Integer -> Integer

factorial n = product [1..n] -- 1*2*3*..*n

3

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Int

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Int

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Int

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Int

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Integer

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Int

[16]: factorial 50

304140932017133780436126081660647688443776415 XXXXXXXXXX

Float Float is a real floating point with single precision.

[17]: circumference :: Float -> Float

circumference r = 2 * pi * r

[18]: circumference 4.0

XXXXXXXXXX

Double Double is a real floating point with double the precision!

[19]: circumference' :: Double -> Double

circumference' r = 2 * pi * r

[20]: circumference' 4.0

XXXXXXXXXX

Bool Bool is a boolean type. It can have only two values: True and False.

Char Char represents a character. It’s denoted by single quotes. A list of characters is a string.

Tuple

• Tuples are types but they are dependent on their length as well as the types of their compo-

nents,

• so there is theoretically an infinite number of tuple types.

• Note that the empty tuple () is also a type which can only have a single value: ()

[21]: :t (12,'a',"a",[1..2], [[1],[2]])

(12,'a',"a",[1..2], [[1],[2]]) :: forall a1 a2 a3. (Enum a1, Num a2, Num a1, Num␣

↪→a3) => (a2, Char, [Char], [a1], [[a3]])

1.2 Type variables

Because head takes a list of any type and returns the first element, so what could it be?

[22]: fun :: (Integral a) => a -> a-> a -> [a]

fun x y z = [x,y,z]

[23]: fun 1 2 3

[1,2,3]

[24]: -- fun :: (Int a) => a -> a-> a -> [a] -- wrong

fun x y z = [x,y,z]

4

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Float

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Double

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bool

https://hackage.haskell.org/package/base/docs/Prelude.html#v:True

https://hackage.haskell.org/package/base/docs/Prelude.html#v:False

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Char

https://hackage.haskell.org/package/base/docs/Prelude.html#v:head

1.2.1 Type variable

Hmmm! What is this a? Is it a type?

• types are written in capital case, so it can’t exactly be a type.

• it’s actually a type variable. That means that a can be of any type.

• This is much like generics in other languages, only in Haskell it’s much more powerful because

it allows us to easily write very general functions if they don’t use any specific behavior of

the types.

• Functions that have type variables are called polymorphic functions.

1.2.2 Type variable examples

Although type variables can have names longer than one character, we usually give them names of

a, b, c, d …

The type declaration of head states that it takes a list of any type and returns one element of that

type.

[25]: :t head

head :: forall a. [a] -> a

[26]: :t fst

fst :: forall a b. (a, b) -> a

• fst takes a tuple which contains two types and returns an element which is of the same type

as the pair’s first component.

• That’s why we can use fst on a pair that contains any two types.

• Note that just because a and b are different type variables, they don’t have to be different

types. It just states that the first component’s type and the return value’s type are the same.

1.3 Typeclasses 101

• A typeclass is a sort of interface that defines some behavior.

• If a type is a part of a typeclass, that means that it supports and implements the behavior

the typeclass describes.

• Typeclasses are NOT like classes in object oriented languages. They are like Java interfaces.

1.3.1 Eq typeclass

What’s the type signature of the == function?

[27]: :t (==)

(==) :: forall a. Eq a => a -> a -> Bool

[28]: (==) 2 3

False

[29]: XXXXXXXXXX

5

https://hackage.haskell.org/package/base/docs/Prelude.html#v:head

https://hackage.haskell.org/package/base/docs/Prelude.html#v:fst

https://hackage.haskell.org/package/base/docs/Prelude.html#v:fst

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-61--61-

5

Note:

• the equality operator, == is a function.

• So are +, *, -, / and pretty much all operators.

• If a function is comprised only of special characters, it’s considered an infix function by

default.

• If we want to examine its type, pass it to another function or call it as a prefix function, we

have to surround it in parentheses.

[30]: :t (==)

(==) :: forall a. Eq a => a -> a -> Bool

• Everything before the => symbol is called a class constraint.

• It reads like this: the equality function takes any two values that are of the same type and

returns a Bool. ### Eq typeclass cont’ed

• The type of those two values must be a member of the Eq class (this was the class constraint).

• The Eq typeclass provides an interface for testing for equality.

• Any type where it makes sense to test for equality between two values of that type should be

a member of the Eq class.

• All standard Haskell types except for IO (the type for dealing with input and output) and

functions are a part of the Eq typeclass.

• The elem function has a type of (Eq a) => a -> [a] -> Bool because it uses == over a list

to check whether some value we’re looking for is in it.

1.3.2 Some basic typeclasses

Eq

• Eq is used for types that support equality testing.

• The functions its members implement are == and /=.

• So if there’s an Eq class constraint for a type variable in a function, it uses == or /= somewhere

inside its definition.

• All the types we mentioned previously except for functions are part of Eq, so they can be

tested for equality.

[31]: 5 == 5

True

[32]: 5 /= 5 -- 5 \= 5

False

[33]: 'a' == 'a'

True

[34]: "Ho Ho" == "Ho Ho"

True

6

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-61--61-

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-43-

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-42-

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-45-

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-47-

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bool

https://hackage.haskell.org/package/base/docs/Prelude.html#t:IO

https://hackage.haskell.org/package/base/docs/Prelude.html#v:elem

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-61--61-

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-61--61-

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-47--61-

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-61--61-

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-47--61-

[35]: 3.432 == 3.432

True

Ord Ord is for types that have an ordering.

[36]: :t (>)

(>) :: forall a. Ord a => a -> a -> Bool

• All the types we covered so far except for functions are part of Ord.

• Ord covers all the standard comparing functions such as >, <, >= and <=.

• The compare function takes two Ord members of the same type and returns an ordering.

• Ordering is a type that can be GT, LT or EQ, meaning greater than, lesser than and equal,

respectively.

• To be a member of Ord, a type must first have membership in the prestigious and exclusive

Eq club.

[37]: "Abrakadabra" < "Zebra"

True

[38]: "Abrakadabra" `compare` "Zebra"

:t compare

LT

compare :: forall a. Ord a => a -> a -> Ordering

[39]: 5 >= 2

True

[40]: 5 `compare` 3

GT

Show

• Members of Show can be presented as strings.

• All types covered so far except for functions are a part of Show.

• The most used function that deals with the Show typeclass is show. It takes a value whose

type is a member of Show and presents it to us as a string.

[41]: output = "The output is: " ++ show 3

output

"The output is: 3"

[42]: show 5.334

7

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Ord

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Ord

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Ord

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-62-

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-60-

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-62--61-

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-60--61-

https://hackage.haskell.org/package/base/docs/Prelude.html#v:compare

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Ord

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Ordering

https://hackage.haskell.org/package/base/docs/Prelude.html#v:GT

https://hackage.haskell.org/package/base/docs/Prelude.html#v:LT

https://hackage.haskell.org/package/base/docs/Prelude.html#v:EQ

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Ord

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Show

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Show

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Show

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Show

"5.334"

[43]: show True

"True"

Read

• Read is sort of the opposite typeclass of Show.

• The read function takes a string and returns a type which is a member of Read.

[44]: read "True" || False

True

[45]: read "8.2" + 3.8

12.0

[46]: read "5" - 2

3

[47]: read "[1,2,3,4]" ++ [3]

[1,2,3,4,3]

But what happens if we try to do just read "4"?

[48]: read "5"

Prelude.read: no parse

The complete error messages: :1:0: Ambiguous type variable a' in the constraint:Read a’

arising from a use of ‘read’ at :1:0-7 Probable fix: add a type signature that fixes these type

variable(s)

• What GHC is telling us here is that it doesn’t know what we want in return.

Let’s take a look at the type signature of read.

[49]: :t read

read :: forall a. Read a => String -> a

It returns a type that’s part of Read but if we don’t try to use it in some way later, it has no way

of knowing which type.

• In the previous uses of read we did something with the result afterwards. That way, GHC

could infer what kind of result we wanted out of our read. If we used it as a boolean, it knew

it had to return a Bool.

• But now, it knows we want some type that is part of the Read class, it just doesn’t know

which one.

8

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Read

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Show

https://hackage.haskell.org/package/base/docs/Prelude.html#v:read

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Read

https://hackage.haskell.org/package/base/docs/Prelude.html#v:read

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Read

https://hackage.haskell.org/package/base/docs/Prelude.html#v:read

https://hackage.haskell.org/package/base/docs/Prelude.html#v:read

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bool

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Read

Explicit type annotation We can use explicit type annotations.

• Type annotations are a way of explicitly saying what the type of an expression should be.

• We do that by adding :: at the end of the expression and then specifying a type. Observe:

[50]: read "5" :: Int

5

[51]: read "5" :: Float

5.0

[52]: read "5" * 4

20

[53]: read "[1,2,3,4]" :: [Int]

[1,2,3,4]

[54]: read "(3, 'a')" :: (Int, Char)

(3,'a')

• Most expressions are such that the compiler can infer what their type is by itself.

• But sometimes, the compiler doesn’t know whether to return a value of type Int or Float

for an expression like read "5".

• To see what the type is, Haskell would have to actually evaluate read "5".

• Haskell is a statically typed language, it has to know all the types before the code is compiled

(or in the case of GHCI, evaluated).

Enum

• Enum members are sequentially ordered types — they can be enumerated.

• The main advantage of the Enum typeclass is that we can use its types in list ranges.

• They also have defined successors and predecessors, which you can get with the

– succ and

– pred functions.

• Types in this class: (), Bool, Char, Ordering, Int, Integer, Float and Double.

[55]: ['a'..'e']

"abcde"

[56]: [LT .. GT]

[LT,EQ,GT]

[57]: [3 .. 5]

[3,4,5]

9

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Int

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Float

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Enum

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Enum

https://hackage.haskell.org/package/base/docs/Prelude.html#v:succ

https://hackage.haskell.org/package/base/docs/Prelude.html#v:pred

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bool

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Char

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Ordering

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Int

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Integer

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Float

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Double

[58]: succ 'B'

'C'

Bounded Bounded members have an upper and a lower bound.

Jupyter Note: Parentheses resolve ambiguity in the following expressions, see IHaskell

Issue #509 The type signature for ‘minBound’ lacks an accompanying binding

[59]: (minBound :: Int)

XXXXXXXXXX

[60]: (maxBound :: Char)

' XXXXXXXXXX'

[61]: (maxBound :: Bool)

True

[62]: (minBound :: Bool)

False

• minBound and maxBound are interesting because they have a type of (Bounded a) => a. In

a sense they are polymorphic constants.

• All tuples are also part of Bounded if the components are also in it.

[63]: (maxBound :: (Bool, Int, Char))

(True, XXXXXXXXXX,' XXXXXXXXXX')

Num

• Num is a numeric typeclass.

• Its members have the property of being able to act like numbers.

[64]: :t 20

20 :: forall p. Num p => p

• It appears that whole numbers are also polymorphic constants.

• They can act like any type that’s a member of the Num typeclass.

[65]: 20 :: Int

20

[66]: 20 :: Integer

20

10

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bounded

https://github.com/gibiansky/IHaskell/issues/509

https://github.com/gibiansky/IHaskell/issues/509

https://hackage.haskell.org/package/base/docs/Prelude.html#v:minBound

https://hackage.haskell.org/package/base/docs/Prelude.html#v:maxBound

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bounded

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Num

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Num

[67]: 20 :: Float

20.0

[68]: 20 :: Double

20.0

[69]: 20.0 :: Int

• No instance for (Fractional Int) arising from the literal ‘20.0’

• In the expression: 20.0 :: Int

In an equation for ‘it’: it = 20.0 :: Int

[70]: :i Num

Integral Integral is also a numeric typeclass.

• Num includes all numbers,including real numbers and integral numbers,

• Integral includes only integral (whole) numbers.

• In this typeclass are Int and Integer.

Floating Floating includes only floating point numbers, so Float and Double.

1.3.3 Number conversions

fromIntegral A very useful function for dealing with numbers is fromIntegral. fromIntegral

:: (Num b, Integral a) => a -> b.

• It takes an integral number and turns it into a more general number.

• For instance, the length function has a type declaration of length :: [a] -> Int instead

of having a more general type of (Num b) => length :: [a] -> b.

• If we try to get a length of a list and then add it to 3.2, we’ll get an error because we tried

to add together an Int and a floating point number.

[71]: XXXXXXXXXX

7.2

[72]: :t length

length :: forall (t :: * -> *) a. Foldable t => t a -> Int

[73]: length [1,2,3,4] + 3.2

• No instance for (Fractional Int) arising from the literal ‘3.2’

• In the second argument of ‘(+)’, namely ‘3.2’

11

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Integral

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Num

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Integral

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Int

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Integer

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Floating

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Float

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Double

https://hackage.haskell.org/package/base/docs/Prelude.html#v:fromIntegral

https://hackage.haskell.org/package/base/docs/Prelude.html#v:length

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Int

In the expression: length [1, 2, 3, 4] + 3.2

In an equation for ‘it’: it = length [1, 2, 3, …] + 3.2

[74]: fromIntegral(length [1,2,3,4]) + 3.2

7.2

Example: * If we examine the type of *, we’ll see that it accepts all numbers.

[75]: :t (*)

4 * 3.4

(*) :: forall a. Num a => a -> a -> a

13.6

• It takes two numbers of the same type and returns a number of that type.

• That’s why (5 :: Int) * (6 :: Integer) will result in a type error

• whereas 5 * (6 :: Integer) will work just fine and produce an Integer because 5 can act

like an Integer or an Int.

• To join Num, a type must already be friends with Show and Eq.

1.4 Summary

• Types: Int/Integer, Float, Double, Bool, Char, Tuple

• Typeclasses: Eq, Ord, Show, Read, Enum, Bounded, Num, Integral, Floating

• Type conversion: fromIntegral, fromRational/toRational, truncate/round/ceiling/floor

• Function declaration

– foo:: a -> a

– foo:: Int -> Float

– foo:: a -> a -> a -> a

– foo:: (Ord a) => a -> b -> c -> a

– foo:: (Integral a) => a -> Int -> a

[76]: foo:: a -> a

foo a = a

:t foo

foo :: forall a. a -> a

[77]: foo:: a -> Int -> a

foo x y = x

12

https://hackage.haskell.org/package/base/docs/Prelude.html#v:-42-

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Integer

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Integer

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Int

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Num

https://hackage.haskell.org/package/base/docs/Prelude.html#t:Show

Types and Typeclasses

Believe the type

Static type system

Type inference

Examine the types of some expressions

Types

Common types

Type variables

Type variable

Type variable examples

Typeclasses 101

Eq typeclass

Some basic typeclasses

Number conversions

Summary

Answered Same DayMay 12, 2021

import Prelude

even' :: [a] ->...

- You have to know HTML , PHP , and SQL . THis is an urgent assignment that I want done in an hour from now or as much of it as possible in an hour. There are 4 problems. I WILL PAY A LOT FOR THE SPEED!Oct 23, 2021
- (1) Assignment description & the files needed p1/Assingment description.docx Lab 2 – Group Lab (100 points) Part 1: Practice on subquery Use university data (The CSV files). Please fill in the SQL and...SolvedOct 22, 2021
- This is an urgent assignment that I want done in the next 5-7 hours. More than happy to pay extra for urgent work. It's 4 basic questions. Must know how use PHP , HTML , and MySQL . The assignment...SolvedOct 22, 2021
- In Assembly Language (asm file) 1. Write a MASM program that generates one random number between 10 and 99. Let us call this number the original random number. Then generate 2 random numbers between...SolvedOct 22, 2021
- Module 6 HA 1/HWA2_MD.zip HWA2_MD/.gitignore *.iml .gradle /local.properties /.idea/caches /.idea/libraries /.idea/modules.xml /.idea/workspace.xml /.idea/navEditor.xml /.idea/assetWizardSettings.xml...SolvedOct 21, 2021

- What will england economy look like in 2050?Oct 23, 2021
- Respond to the following: Go to the Build-A-Bear website at Shop, Explore andPlay at Build-A-Bear and examine its store-based strategy mix. Reread the information regarding the company in Chapter 1 of...Oct 23, 2021
- An insect is laying 2000 eggs. A viable offspring develops from each egg (mutually independently from all other eggs) with a probability of XXXXXXXXXXDetermine the probability of having at least two...Oct 23, 2021
- Arrays and File I/O Create a program in a class called PlayGame.java that reads data from two files ShipPositionsPlayerOne.txt and ShipPositionsPlayerTwo.txt and plays the board game Battleship. A log...Oct 23, 2021
- Diversity Case Study Analysis In 2003, clothing retailer Abercrombie & Fitch (A&F) was sued by current and past members of its sales force as well as by applicants who were denied jobs, all of whom...Oct 23, 2021

Copy and Paste Your Assignment Here

Copyright © 2021. All rights reserved.