diff --git a/type-classes/basic-classes/eq-equality-types.md b/type-classes/basic-classes/eq-equality-types.md index 93e2653..70a8553 100644 --- a/type-classes/basic-classes/eq-equality-types.md +++ b/type-classes/basic-classes/eq-equality-types.md @@ -1,13 +1,13 @@ # Eq – Equality Types -The `Eq` class supports the comparison methods \(equality and inequality\), so any two values of a type that is an instance of the `Eq` class can be compared using the functions: +The `Eq` class supports the **comparison methods** (equality and inequality), so any two values of a type that is an instance of the `Eq` class can be compared using the functions: ```haskell (==) :: a -> a -> Bool (/=) :: a -> a -> Bool ``` -We have already used these functions many times, and we were able to because all the basic types \(`Char`, `Bool`, `Int`....\) are instances of the `Eq` class. Classes are defined using the `class` keyword followed by the class name, the type specification and the where keyword, followed by the default definitions of the class methods: +We have already used these functions many times, and we were able to because all the basic types (`Char`, `Bool`, `Int`....) are instances of the `Eq` class. Classes are defined using the `class` keyword followed by the **class name**, the **type specification** and the `where` keyword, followed by the **default definitions** of the class methods: ```haskell class Eq a where @@ -20,7 +20,7 @@ class Eq a where x == y = not (x /= y) ``` -We see the two default methods defined in terms of each other, which means we need to define one of them in a clear way to have a complete definition for an instance. For example, the `Bool` type can be made an instance of the `Eq` class with: +We see the two default methods above defined in terms of each other, which means we need to define one of them in a clear way to have a complete definition for an instance. For example, the `Bool` type can be made an instance of the `Eq` class with: ```haskell instance Eq Bool where @@ -37,4 +37,3 @@ instance Eq Bool where ``` Keep in mind that the definitions of the required functions can be as simple or as complicated as you like, and default definitions can be overwritten when declaring instances. - diff --git a/type-classes/basic-classes/ord-ordered-types.md b/type-classes/basic-classes/ord-ordered-types.md index 658f2e3..6bc01b5 100644 --- a/type-classes/basic-classes/ord-ordered-types.md +++ b/type-classes/basic-classes/ord-ordered-types.md @@ -1,6 +1,6 @@ # Ord – ordered types -The `Ord` class requires any type that wants to be an instance of it to first be an instance of the Eq class by using a class constraint, and additionally, to support the following methods: +The `Ord` class requires any type that wants to be an instance of it to first be an instance of the `Eq` class by using a **class constraint**, and additionally, to support the following methods: ```haskell class (Eq a) => Ord a where @@ -43,4 +43,3 @@ class (Eq a) => Ord a where ``` All the basic types of Haskell are also instances of the `Ord` class. - diff --git a/type-classes/basic-classes/read-readable-types.md b/type-classes/basic-classes/read-readable-types.md index 437e281..caab8fa 100644 --- a/type-classes/basic-classes/read-readable-types.md +++ b/type-classes/basic-classes/read-readable-types.md @@ -1,6 +1,6 @@ # Read – readable types -The `Read` class supports reading and conversion of string representation of values into actual types using the `read` method. All the basic types of Haskell are also instances of the `Read` class. Note that we sometimes have to specify the type to be read in cases where the intended cannot be inferred: +The `Read` class supports reading and conversion of string representations of values into actual types using the `read` method. All the basic types of Haskell are also instances of the `Read` class. Note that we sometimes have to specify the type to be read in cases where the intended type cannot be inferred: ```haskell ghci> read "False" @@ -10,10 +10,9 @@ ghci> read "False" :: Bool False ``` -That is, in the first case, the compiler does not know whether to read `"False"` as a type of `String` or `Bool`, so it throws an exception, while in the second case, we explicitly state that we want to read it as a `Bool`. However, if we had some additional boolean function \(e.g. negation\) to be called on the read argument, the compiler could automatically infer the wanted type: +That is, in the first case, the compiler does not know whether to read `"False"` as a type of `String` or `Bool`, so it throws an exception, while in the second case, we explicitly state that we want to read it as a `Bool`. However, if we had some additional boolean function (e.g. negation) to be called on the read argument, the compiler would be able to automatically infer the wanted type: ```haskell ghci> not $ read "False" True ``` - diff --git a/type-classes/basic-classes/show-showable-types.md b/type-classes/basic-classes/show-showable-types.md index a5ce719..7b74252 100644 --- a/type-classes/basic-classes/show-showable-types.md +++ b/type-classes/basic-classes/show-showable-types.md @@ -3,7 +3,7 @@ The `Show` class is used for types whose values can be represented as strings and support the `show` method. All the basic types of Haskell are also instances of the `Show` class. ```haskell -show :: a -> StringList +show :: a -> String ghci> show False "False" @@ -12,5 +12,3 @@ ghci> show [1..3] "[1, 2, 3]" ``` - - diff --git a/type-classes/derived-instances.md b/type-classes/derived-instances.md index 34c6db5..3c996ee 100644 --- a/type-classes/derived-instances.md +++ b/type-classes/derived-instances.md @@ -7,7 +7,7 @@ data Bool = False | True deriving (Eq, Ord, Show, Read) ``` -It is as if we are stating that the new data type `Bool` can have two values \(two nullary constructors `True` and `False`\) and it should also be made an instance of the classes `Eq`, `Ord`, `Show` and `Read`, but we let the compiler write the actual code for us using the default definitions. Note that for the `Ord` class, the default ordering will be the order in which the constructors are defined – in this case, `True` comes after `False` and is, therefore "greater than" `False`. With this definition, we can use methods of all the class instances included on the type `Bool`: +It is as if we are stating that the new data type `Bool` can have two values (two nullary constructors `True` and `False`) and it should also be made an instance of the classes `Eq`, `Ord`, `Show` and `Read`, but we let the compiler write the actual code for us using the default definitions. Note that for the `Ord` class, the default ordering will be the order in which the constructors are defined – in this case, `True` comes after `False` and is, therefore _"greater than"_ `False`. With this definition, we can use methods of all the class instances included with the type `Bool`: ```haskell ghci> True == True @@ -22,4 +22,3 @@ ghci> show True ghci> read "False" False ``` - diff --git a/type-classes/exercise-making-a-card-deck-type.md b/type-classes/exercise-making-a-card-deck-type.md index adfc916..b857cd3 100644 --- a/type-classes/exercise-making-a-card-deck-type.md +++ b/type-classes/exercise-making-a-card-deck-type.md @@ -1,6 +1,6 @@ # Exercise – Making a Card Deck Type -Let's now try to implement a data type that will represent a deck of cards. First, we can think about what type would be fitting for a card deck – a list of cards would be a good representation. But then what type is fitting for a single card? **Each card should have a rank and a suit** so we can make another type for cards that has the type of a tuple `(Rank, Suit)`. Let's start at the lowest level, the `Rank` and `Suit` type, and remember that we already defined the `Suit` type, but we will now also derive the `Show` class for it: +Let's now try to implement a data type that will represent a deck of cards. First, we can think about what type would be fitting for a card deck – a list of cards would be a good representation. But then what type is fitting for a single card? **Each card should have a rank and a suit** so we can make another type for cards that has the type of a tuple `(Rank, Suit)`. Let's start at the lowest level, the `Rank` and `Suit` type. Remember that we already defined the `Suit` type, but we will now also derive the `Show` class for it: ```haskell data Suit = Hearts @@ -59,7 +59,7 @@ Similarly, we can define a deck of cards as a type synonym for a list of `Card` type Deck = [Card] ``` -We have all the required types for actually building a deck now, so let's make a function for that purpose. We will use list comprehension and take advantage of the fact that `Rank` supports enumeration: +We have all the required types for actually building a deck now, so let's make a function for that purpose. We will use [list comprehension](../list-comprehensions/list-comprehensions.md) and take advantage of the fact that `Rank` supports [enumeration](basic-classes/enum-enumeration-types.md): ```haskell buildDeck :: Deck @@ -86,5 +86,3 @@ Hearts),(King, Diamonds),(King, Spades),(King, Clubs),(Ace, Hearts),(Ace, Diamonds),(Ace, Spades),(Ace, Clubs)]" ``` - - diff --git a/type-classes/introduction.md b/type-classes/introduction.md index 7e43bde..d525d80 100644 --- a/type-classes/introduction.md +++ b/type-classes/introduction.md @@ -1,6 +1,4 @@ # Introduction -**Classes** in Haskell are used to ensure that certain methods \(functions\) are supported by any type that is an instance of the given `Class` \(in other words, belongs to the given class\). We can think of classes as **collections of types that support the operations of that class**. Let's explore the basic built-in classes in Haskell to get a better idea. - - +**Classes** in Haskell are used to ensure that certain **methods** (functions) are supported by any type that is an instance of the given `Class` (in other words, belongs to the given class). We can think of classes as **collections of types that support the operations of that class**. Let's explore the basic built-in classes in Haskell to get a better idea.