Skip to 0 minutes and 5 seconds JEREMY: Hi. In any high-level programming language, there are various number like types. In Haskell, for instance, we have seen Int so far. There are also float and infinite precision integers, like BigIntegers in Java to name a few more types. Now, here is a key insight. Many arithmetic functions can be applied to values from any number like type, for example, addition or multiplication. Here’s 2 + 2, which makes 4. Here is 2 + pi, which makes 5.1415, and so on. Here’s 2 * 2, which makes 4. And here’s 2 * pi, which makes 6.2831, so on. This is where the notion of type classes comes in handy. A type class specifies a family of types that provide implementations for common functions.
Skip to 1 minute and 22 seconds Let’s have a look at the type of (+).
Skip to 1 minute and 32 seconds Sorry, I need to put (+) inside brackets because it’s an infix operator.
Skip to 1 minute and 40 seconds This says, given a type a– some people pronounce this as alpha– given a type a belonging to the Num type class, then the + function takes two a parameters and returns an a result. a is a type variable. The part of the type before the double arrow here is called the context of the type. This expresses type class membership for type variables like a. So a type class is a generalized family of similar types.
Skip to 2 minutes and 33 seconds Let’s think about some other the type classes. The Eq type class means we can compare values of such types equality with the (==) operator.
Skip to 2 minutes and 50 seconds We see that given the context of the type a that is an instance of the Eq type class, then the (==) function takes two parameters of type a and return to Boolean result. So we can see that ints are an instance of the Eq type class.
Skip to 3 minutes and 19 seconds The Ord type class means we can order values of such types with relational operators like less than and greater than.
Skip to 3 minutes and 33 seconds This is like the IComparable interface in C#.
Skip to 3 minutes and 45 seconds For strings, less than implements a lexicographic ordering.
Skip to 3 minutes and 54 seconds The Show type class means we can generate string values that represent values of such types, like toString() in Java. So if I say, show 42 integer value, then I get back the string 42.
Skip to 4 minutes and 16 seconds If I say show False, I get back the string False.
Skip to 4 minutes and 28 seconds The Read type class means we can generate values of such types from string values. So I’m going to say read “1” so string. Now, this doesn’t work at the moment because I need to say that the thing I’m reading should be of type Int. Now, it works. Again, I could say read “True,” which should be of type Bool, and I get back a Boolean type– rather, a value of a Boolean type.
Skip to 5 minutes and 18 seconds To specify that a type belongs to a type class, for now, we will use the deriving clause in the type definition. Let’s go back to our SimpleNum class. Remember, we can only count values One, Two, and Many. Data SimpleNum = One, Two, Many. And this type is deriving (Show, Read).
Skip to 5 minutes and 59 seconds The set of type classes that this type is an instance of are in parentheses in the deriving clause. Now, this means we can convert SimpleNum values into strings using the show function, and vice versa using the read function. Let’s say show One, show Two, show Many. And in each case, we return a string.
Skip to 6 minutes and 33 seconds Let’s try to read “One”. We get an error because read doesn’t know what the type of One to be– the string One to be– when we read it. So let’s say we want this to be of type SimpleNum, and how it works.
Skip to 6 minutes and 53 seconds Let’s try comparing SimpleNum values for equality.
Skip to 7 minutes and 2 seconds Does One == One? No. Look at the error message. SimpleNum types are not instances of the Eq type class. So let’s add the Eq type class to the deriving clause in the SimpleNum type definition. Look, now, we have three type classes (Show, Read, Eq).
Skip to 7 minutes and 34 seconds Does One == One now? Yes, it does. Does One == Two? No, it doesn’t. Does One == “One”? No, because SimpleNums are of a different type two strings, which a character lists.
Skip to 8 minutes and 3 seconds Again, there’s a default implementation of ==, which is being used to compare SimpleNums.
Skip to 8 minutes and 11 seconds There is a mechanism for defining type class function implementations, but we’ll save this discussion for later on in the course.
Skip to 8 minutes and 22 seconds Note that type classes were one of the early innovations of the Haskell programming language. The type class constrains member types to provide functions that conform to certain type signatures effectively, API constraints. This is a little like object-oriented programming. Type classes are like interfaces in C# and Java. Types in the type class are like concrete implementations of the interface. Type classes provide a neat mechanism to enable operator overloading in the Haskell language. We’ve seen this with functions like ==, and relational operators, and the show and read functions. We’ll explore type classes in more detail later on in the course. But for now, goodbye.
Inevitably, we have glossed over some of the more complex parts of Haskell while we have been introducing the language. Now it’s time to explore one of the ideas we have bumped into on several occasions already — type classes.
What’s the type of
42? Either type
42 into the online interpreter or enter
in GHCi. Either way, you should get back
Num a => a — whereas you might have thought the answer should be
Num is a type class, which specifies a family of types including integer and floating-point types.
We also anticipated type classes when we used the
deriving Show clause to print out our custom data types. Now it’s time to explain type classes in more detail. Please watch the video and think about the concepts. Do type classes remind you of features in other languages? Leave your thoughts in the comments section.
© University of Glasgow