I have been programming Haskell for a while now, and keep running across strange terms from type theory, or category theory, or lambda calculus or whatever, ususally related to type-classes in the Haskell library. This page attempts to keep a glossary with simple explanations and examples for each type-class. I primarily use as my examples: Maybe, lists, and my Point3 vector type, as these are all fairly straightforward.
pure 4 :: [Int] == [4]
pure 4 :: Maybe Int == Just 4
pure 4 :: Point3' Int == Point3 (4, 4, 4)
add :: Point3' Int -> Point3' Int -> Point3' Int
add = liftA2 (+)
boundingBox :: Ord a => [Point2' a] -> (Point2' a, Point2' a)
boundingBox = foldl1 (liftA2 min) &&& foldl1 (liftA2 max) -- Uses Arrow
Example instance:
instance Applicative Point3' where
pure a = Point3 (a, a, a)
(<*>) (Point3 (fa, fb, fc)) (Point3 (a, b, c)) = Point3 (fa a, fb b, fc c)
f &&& g == \a -> (f a, g a) f *** g == \(a, b) -> (f a, g b) first f == \(a, b) -> (f a, b) second f == \(a, b) -> (a, f b)
toList (Point3 (3,4,5)) == [3,4,5]
pointsEqual :: Eq a => Point3' a -> Point3' a -> Bool
pointsEqual a b = foldr (&&) True $ liftA2 (==) a b -- Uses Applicative too
Example instance:
instance Foldable Point3' where
foldr f t (Point3 (x, y, z)) = x `f` (y `f` (z `f` t))
class Functor f where
fmap :: (a -> b) -> f a -> f b
The fmap function applies the function to all instances of the inner type
throughout the wrapper, e.g. to every element in a collection. For example:
fmap (+1) (Just 6) == Just 7
fmap (+1) Nothing == Nothing
fmap (+4) [1,2,3] == [5,6,7]
| LHS | RHS | >> | `mappend` * | `mplus` * | ||
|---|---|---|---|---|---|---|
| Nothing | Nothing | Nothing | Nothing | Nothing | ||
| Nothing | Just b | Nothing | Just a | Just a | ||
| Just a | Nothing | Nothing | Just b | Just b | ||
| Just a | Just b | Just b | Just (a `mappend` b) | Just a |
newtype IntAdd = IntAdd Int
instance Monoid IntAdd where
mempty = IntAdd 0
mplus (IntAdd x) (IntAdd y) = IntAdd (x + y)