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.

Haskell-related Glossary

**Applicative**: While the fmap function of Functor (see Functor, below) is useful, it cannot be used, for example, to zip two data structures together. While Applicative is quite bizarre at first, it allows you to use liftA2, which can be thought of as the Applicative/Functor version of liftM2, or the Functor version of zipWith. From Applicative, I mainly use liftA2 and the pure function (which creates an item, filling every slot with the given value). Example uses: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)

**Arrows**: When you manipulate things inside a monad, there is no way of keeping track of what you started with. If you have IO Int, that's all you have. Arrows allow a bit extra, so that you can parameterise over a type you began with. For example, the function arrow -> is an arrow. They may be more general than monads, but I've yet to use one in a practical circumstance. What I do use are the &&& and *** operators (as well as the first and second functions), which can be useful with the function arrow (allowing you to manipulate pairs more easily). Here are the equivalent definitions in lambdas for functions: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)

**Foldable**: A generalisation of foldr that can work with any wrapper type. The function toList is supplied built on top of Foldable, and this can be useful with various types (such as Seq from Data.Sequence), as well as your own. There is also an implementation of mapM_ for all Foldable things. Example uses: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))

**Functor**: A functor is a wrapper. Maybe is a functor, as are lists. The functor type-class has one method: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]

**Merging Maybe:**: There are many different ways to merge two Maybe values in Haskell; here's a table (an asterisk indicates that the types must be the same):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 **Monoid**: A monoid is really a pair of things: an associative operator and an identity element. For example, + and 0, or * and 1, or ++ and []. Because Haskell cannot have a type-class parameterised by an operator, for types that can be part of multiple monoids, you use a newtype. Example instance:newtype IntAdd = IntAdd Int instance Monoid IntAdd where mempty = IntAdd 0 mplus (IntAdd x) (IntAdd y) = IntAdd (x + y)

**Traversable**: This class is for everyone who ever wanted to use mapM or sequence on a Map/Set/Sequence. I only ever use the mapM function from this class, on Sequences and Maps.