पाठ 8 / 25
Type Classes and Instances
Use and define type classes, derive instances and understand constraints.
Ad hoc polymorphism
A type class declares operations that types can support, like an interface: class Show a where show :: a -> String. An instance provides the implementation for a specific type: instance Show Paise where .... Functions use constraints to require capabilities: maximum :: Ord a => [a] -> a works for any ordered type. Common classes: Eq (==), Ord (compare, <), Show (debug strings), Read (parsing, best avoided for user input), Num, Integral, Fractional, Enum, Bounded, Semigroup (<>) and Monoid (mempty), and the structural classes Functor, Foldable, Traversable, Applicative and Monad. Many instances can be derived automatically (deriving (Show, Eq, Ord)), and extensions such as DeriveGeneric, DeriveAnyClass and DerivingVia derive more. Classes can have default methods and superclasses (class Eq a => Ord a). Unlike interfaces in OOP, instances can be added to existing types after the fact, but avoid orphan instances (instances defined in neither the class's nor the type's module), which can conflict.
Defining a class and instances
A HasArea class, a custom Show and a Monoid for money.
data Shape = Circle Double | Rect Double Double
deriving (Show, Eq)
class HasArea a where
area :: a -> Double
describe :: a -> String
describe x = "area " ++ show (area x) -- default method
instance HasArea Shape where
area (Circle r) = pi * r * r
area (Rect w h) = w * h
newtype Paise = Paise Int
deriving (Eq, Ord)
instance Show Paise where
show (Paise p) = "Rs " ++ show (p `div` 100) ++ "." ++ pad (p `mod` 100)
where
pad n = if n < 10 then '0' : show n else show n
instance Semigroup Paise where
Paise a <> Paise b = Paise (a + b)
instance Monoid Paise where
mempty = Paise 0
largestArea :: HasArea a => [a] -> Double
largestArea = maximum . (0 :) . map area
main :: IO ()
main = do
putStrLn (describe (Rect 3 4)) -- area 12.0
print (largestArea [Circle 1, Rect 2 5]) -- 10.0
print (mconcat [Paise 4950, Paise 19900, Paise 5]) -- Rs 248.55
print (maximum [Paise 300, Paise 120]) -- Rs 3.00Job qualifications
A type class is a qualification such as "can drive". A function that needs a driver states the constraint (Drives a =>) without caring who it is, and each type proves it holds the qualification by providing an instance.
त्वरित जाँच: What does the constraint in `sort :: Ord a => [a] -> [a]` mean?
- a must be a list
- a must be Int
- sort returns an Ord
- sort works for any type a that has an Ord instance
Answer
sort works for any type a that has an Ord instance — Constraints restrict type variables to types with the required instances.