Skip to content

Commit ff7014a

Browse files
committed
Add type-variables and typeclasses
1 parent 75080c7 commit ff7014a

File tree

6 files changed

+186
-6
lines changed

6 files changed

+186
-6
lines changed

02_starting-out/lists.hs

+5-4
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ woot = ['w','o'] ++ ['o','t']
2626
-- So using cons operator is better which useful for
2727
-- putting something at the beginning of a list.
2828
-- : function takes a element and a list.
29-
smallCat = 'A':" SMALL CAT"
30-
someNumbers = 5:[1,2,3,4]
29+
smallCat = 'A' : " SMALL CAT"
30+
someNumbers = 5 : [1,2,3,4]
3131

3232
-- ++ function takes two lists.
3333
-- : function takes a element and a list.
@@ -61,7 +61,7 @@ isListEmpty list = areListsEqual list []
6161
-- > last [...] (returns last element)
6262
-- > tail [...] (returns everything except first element)
6363
-- > init [...] (returns everything except last element)
64-
-- > length [...] (returns length of list)
64+
-- > length [...] (returns length of list as Integral, mostly we convert it to Num with fromIntegral function)
6565
-- > null [...] (returns True if list is empty, otherwise False) (Use null instead of list==[])
6666
-- > reverse [...] (returns reversed list)
6767
-- > take n [...] (returns a list which contains first n element of the list)
@@ -161,4 +161,5 @@ removeNonUppercase st = [ c | c <- st, c `elem` ['A'..'Z']]
161161
-- Nested list comprehensions are also possible if you're operating on lists that contain lists.
162162
-- Let's remove all odd numbers without flattening the list.
163163
multiNumberList = [[1,3,5,2,3,1,2,4,5], [1,2,3,4,5,6,7,8,9], [1,2,4,2,1,6,3,1,3,2,3,6]]
164-
multiNumberList' = [ [ x | x <- xs, even x ] | xs <- xxs]
164+
removeOddNumbersFromMultiDList xxs = [ [ x | x <- xs, even x ] | xs <- xxs]
165+
-- => removeOddNumbersFromMultiDList multiNumberList

02_starting-out/operators.hs

+10
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,13 @@
66
-- /= means not equal in haskell
77
-- => 5 /= 4
88
-- ==> True
9+
10+
-- Pretty much all operators are functions in Haskell.
11+
-- You can use them infix mode by default.
12+
-- If a function is comprised only of special characters, it's considered an infix function by default.
13+
-- But when you want to pass it to another function or call it as a prefix function,
14+
-- you have to surround it in parentheses
15+
16+
sumTwo a b = (+) a b
17+
isEqual a b = (==) a b
18+
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
-- # http://learnyouahaskell.com/types-and-typeclasses#type-variables
2+
3+
-- LOAD THIS FILE WITH ":l type-variables" within repl (ghci)
4+
-- and reload with ":r"
5+
6+
-- Types are written in capital case.
7+
-- But type variables are write in lower case.
8+
9+
-- Type variables are like Generics in other languages.
10+
-- But more powerful because it allows us to easily write very general functions
11+
-- if they don't use any specific behavior of the types in them.
12+
13+
-- Functions that have type variables are called polymorphic functions.
14+
15+
-- Type variables can have names longer than one character,
16+
-- but we usually give them names of a, b, c, d.
17+
18+
-- For example getFirstOfList takes an list of type a, and returns a value of type a.
19+
-- The "a" is the type variable in type definition.
20+
getFirstOfList :: [a] -> a
21+
getFirstOfList list = list !! 0
22+
23+
-- For example fst takes a tuple and returns first element of tuple.
24+
-- => :t fst
25+
-- ==> fst :: (a, b) -> a
26+
-- Because a and b is type variables that taken tuple have and a is the type what it returns.
27+
-- a and b dont have to be different types.
28+
-- It just states that the first component's type and the return value's type are the same.
29+
+136
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
-- # http://learnyouahaskell.com/types-and-typeclasses#typeclasses-101
2+
3+
-- LOAD THIS FILE WITH ":l typeclasses" within repl (ghci)
4+
-- and reload with ":r"
5+
6+
-- Typeclasses are like Interfaces that defines some behavior.
7+
-- If a type is a part of a typeclass, that means that it supports and
8+
-- implements the behavior the typeclass describes.
9+
10+
-- Lets check type definition of == function/operator.
11+
-- => :t (==)
12+
-- ==> (==) :: (Eq a) => a -> a -> Bool
13+
14+
-- Everything before the => symbol is called a class constraint.
15+
-- So we can read this type definition as;
16+
-- (==) takes two params of same type and returns a Bool type value,
17+
-- BUT two params must must be members of the Eq class.
18+
-- In this case the Eq typeclass provides an interface for testing for equality.
19+
20+
-- All standard Haskell types except for IO and functions are a part of the Eq typeclass.
21+
22+
-- Example;
23+
-- The elem function has a type of (Eq a) => a -> [a] -> Bool.
24+
-- Because it uses == operator to check values.
25+
-- So definition means function will take a type named a,
26+
-- which implements the behaviors that Eq class describes.
27+
28+
-- We can also see type classes when defining functions without types.
29+
-- Haskell's type inference will ad Eq for us.
30+
-- => iseq x y = x == y
31+
-- => :t iseq
32+
-- ==> iseq :: Eq a => a -> a -> Bool
33+
34+
-- Some Basic Typeclasses:
35+
36+
-- > Eq
37+
-- is used for types that support equality testing.
38+
-- members of it implements == and /=
39+
-- if a function type definition includes Eq it means function will use == or /=
40+
-- All the types we mentioned previously except for functions are part of Eq.
41+
42+
-- > Ord
43+
-- is for types that have an ordering.
44+
-- covers all the standard comparing functions such as >, <, >= and <=
45+
-- To be a member of Ord, a type must first be a member of Eq.
46+
-- All the types we covered so far except for functions are part of Ord.
47+
-- For example:
48+
-- compare functions takes two arguments which are members of Ord,
49+
-- and returns an value of Ordering type.
50+
-- Ordering is a type that can be GT, LT or EQ, meaning greater than, lesser than and equal.
51+
52+
-- > Show
53+
-- is for types that can be presented as string.
54+
-- All the types we covered so far except for functions are part of Show.
55+
-- Check some functions for example.
56+
57+
-- > Enum
58+
-- Enum members are sequentially ordered types — they can be enumerated.
59+
-- We can use them in ranges like;
60+
-- => ['a'..'e']
61+
-- ==> "abcde"
62+
-- We can get them successors and predecesors because they have defined successors and predecesors;
63+
-- => succ 1
64+
-- ==> 2
65+
-- => pred 5
66+
-- ==> 4
67+
-- Types in this class: (), Bool, Char, Ordering, Int, Integer, Float and Double.
68+
69+
-- > Bounded
70+
-- Bounded members have an upper and a lower bound.
71+
-- Like Int, Char, Bool.
72+
-- We can get bounds with minBound maxBound functions.
73+
-- => maxBound Bool
74+
-- ==> True
75+
-- => minBound Bool
76+
-- ==> False
77+
-- All tuples are also part of Bounded if the components are also in it.
78+
79+
-- > Num
80+
-- Num is a numeric typeclass. Its members have the property of being able to act like numbers.
81+
-- Wole numbers are also polymorphic constants. They can act like any type that's a member of the Num typeclass.
82+
-- => :t 20
83+
-- ==> (Num t) => t
84+
-- Int, Integer, Float, Double are types that are in the Num typeclass.
85+
-- If we examine the type of *, we'll see that it accepts all numbers.
86+
-- => :t (*)
87+
-- ==> (*) :: (Num a) => a -> a -> a
88+
-- To join Num, a type must already be friends with Show and Eq.
89+
90+
-- > Integral
91+
-- Integral is also a numeric typeclass.
92+
-- Num includes all numbers, including real numbers and integral numbers,
93+
-- Integral includes only integral (whole) numbers. In this typeclass are Int and Integer.
94+
95+
-- > Floating
96+
-- Includes only floating point numbers, so Float and Double.
97+
98+
-- > Read
99+
-- Takes a string and return a type which is also a member of Read.
100+
-- Which type of value it should return?
101+
-- Compiler will told him by infering our usage of value.
102+
-- For example:
103+
-- => read "8.2" + "3.8"
104+
-- ==> 12
105+
-- => "True" || False
106+
-- ==> True
107+
-- => read "[1,2,3,4]" ++ [3]
108+
-- ==> [1,2,3,4,3]
109+
-- => read "1" : [2]
110+
-- ==> [1,2]
111+
-- As you can see read returns a type which is "a" (type variable) by knowing what we are doing with that value.
112+
113+
-- Explicit Type Annotations
114+
115+
-- Type annotations are a way of explicitly saying what the type of an expression should be.
116+
-- We do that by adding :: at the end of the expression and then specifying a type.
117+
-- For example, when we dont using return value from read, compiler cant know what type it should return.
118+
-- So we have to explicitly told type.
119+
-- => read "5" :: Int
120+
-- ==> 5
121+
-- => read "(3, 'a')" :: (Int, Char)
122+
-- ==> (3, 'a')
123+
124+
-- Multiple Class Constraints
125+
126+
-- It's totaly ok to have multiple Class Constraits.
127+
-- For example lets examine function fromIntegral.
128+
-- It takes an integral number and turns it into a more general number.
129+
-- => :t fromIntegral
130+
-- ==> fromIntegral :: (Num b, Integral a) => a -> b
131+
-- So it takes a Integral and returns a Num.
132+
133+
-- Order of constraits is not importanti constraits mean our function will work with that typeclasses.
134+
-- Lets swap places of fromIntegral constraits:
135+
fromIntegral' :: (Integral a, Num b) => a -> b
136+
fromIntegral' n = fromIntegral n

03_types-and-typeclasses/types.hs

+4-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
-- You can use GHCI to examine the types of an expressions.
1010
-- You can also check type of functions with :t because Functions are expressions too.
1111
-- You can also write a function without type and then check which type it gain by compiler with :t
12-
12+
-- for example;
13+
-- => sumTwo x y = x + y
14+
-- => :t sumTwo
15+
-- ==> sumTwo :: Num a => a -> a -> a
1316

1417
-- Explicit types are always denoted with the first letter in capital case. Like "Char".
1518

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@
1313
- [conclusion](/02_starting-out/conclusion.hs)
1414
3. Types and Typeclasses ([Book Page](http://learnyouahaskell.com/types-and-typeclasses))
1515
- [types](/03_types-and-typeclasses/types.hs)
16-
- ...
16+
- [type variables](/03_types-and-typeclasses/type-variables.hs)
17+
- [typeclasses](/03_types-and-typeclasses/typeclasses.hs)

0 commit comments

Comments
 (0)