# Typeclassopedia Exercises ## Metadata **Status**:: #x **Zettel**:: #zettel/fleeting **Created**:: [[2026-02-02]] **URL**:: [haskell.org](https://wiki.haskell.org/Typeclassopedia) **Highlights**:: [[Brent Yorgey - Typeclassopedia (Highlights)]] ## Functor ### Implement Functor instances for `((,) e)` and for Pair ```haskell data Pair a = Pair a a ``` The prototype of `fmap` for `Pair` is ```haskell fmap :: (a -> b) -> Pair a -> Pair b ``` ### Is the composition of two Functors is also a Functor? [Data.Functor.Compose](https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Compose.html) ### Notes - `(<gt;)` infix alias - `(gt;)` and `(<$)` replace a value in the context. The arrow points to the new value. - `void` puts `()` in the context. - See `Data.Functor` ## Applicative ### The `pure` for `ZipList` Since zip caps the longer list, `pure id <*> x == x` requires that the list created by `pure` is not shorter than any list. It can only be an infinite list repeating the given value, so `pure = ZipList . repeat`. ### `ApplicativeDo` ```haskell -- | -- >>> myApp (+) (Just 2) (Just 3) -- Just 5 myApp :: (a -> b -> c) -> Maybe a -> Maybe b -> Maybe c myApp g x y = do x' <- x y' <- y pure $ g x' y' ``` ### Notes - `pure` turns a value into an effective-free context. - `(*>)` and `(<*)` sequences both computation contexts but keep only result on the arrow direction. - `(<**>)` flips `(<*>)` but reserve the sequence. - `when`, `unless` in `Control.Monad` performs the computation conditionally and drops the result. - See `Control.Applicative` - It's a bit tricky to implement Applicative for a function newtype. ```haskell (TFun g) <*> (TFun h) = TFun $ (\x -> g x . h $ x) ```