A type class in Haskell is a construct that allows you to define a specific interface that acts as a contract for various types, similar to interfaces or traits in other programming languages. Type classes allow you to define a set of methods with a particular behavior that multiple types can implement, which enables ad-hoc polymorphism. This means that a single function can work with arguments that belong to different types, as long as they belong to the same type class.
To define a type class, you use the ‘class‘ keyword, followed by the type class name and its methods’ type signatures. Then, you can create instances of the type class for specific types using the ‘instance‘ keyword.
Here is an example of how to define a type class called ‘Printable‘:
class Printable a where
toString :: a -> String
This type class has a single method called ‘toString‘ that converts a value of type ‘a‘ into a ‘String‘. The ‘a‘ acts as a type variable, meaning that any type that implements the type class must provide an implementation for this method.
Next, let’s create instances of the ‘Printable‘ type class for a few common types:
instance Printable Int where
toString x = show x
instance Printable Bool where
toString True = "true"
toString False = "false"
instance Printable Char where
toString c = [c]
Now, we can define a polymorphic function ‘printIt‘ that works with any type ‘a‘ that is an instance of the ‘Printable‘ type class:
printIt :: Printable a => a -> IO ()
printIt x = putStrLn (toString x)
main :: IO ()
main = do
printIt (42 :: Int)
printIt True
printIt 'A'
In this code, ‘printIt‘ uses the ‘toString‘ method from the ‘Printable‘ type class to convert its argument to a ‘String‘, which is then printed to the standard output. Since ‘Int‘, ‘Bool‘, and ‘Char‘ are all instances of ‘Printable‘, the ‘printIt‘ function works for values of all these types.
Here’s a common usage of type classes with a chart comparison for better understanding:
| Function | Type Signature | Type class constraint | Description |
|---|---|---|---|
| min | Ord a => a -> a -> a | Ord | Returns the minimum of two values |
| (==) | Eq a => a -> a -> Bool | Eq | Checks if two values are equal |
| (+) | Num a => a -> a -> a | Num | Adds two numbers |
| show | Show a => a -> String | Show | Converts a value to a readable string |
| read | Read a => String -> a | Read | Parses a string into a value |
In summary, a type class in Haskell is a way to define a specific interface for different types, allowing ad-hoc polymorphism with a single function working on arguments of different types, as long as they belong to the same type class.