New practioners of Haskell may find themselves guided by this page. Here
are things I wish I knew when I started learning the language. **This page
may be slightly out of date; I need to update it.**

## XMonad

XMonad is a wonderful tiling window manager that also happens to
be written in Haskell. You can grab it with `cabal install xmonad`

. Plenty
of people have published their `xmonad.hs`

files, so I won't belabor the point,
but here are some useful tricks I've accumulated:

- If you use
`.xsession`

to start up XMonad from GDM without using`gnome-session`

, you should also start up`gnome-settings-daemon`

,`gnome-power-manager`

and`gnome-screensaver`

. Among the things these will fix include your power button, locking your screen and your desktop background. - I hate
`gnome-panel`

with a passion, but without some sort of panel you can't run Network Manager. I use stalonetray, with the flags`-bg '#000000' -i 8 -geometry 19x1+680+0`

: in particular,`-i 8`

sets the icon size to something that fits snugly in a default xmobar. Once the tray is running, spin up`nm-applet`

. - Transparency is good. Windows that spawn on the same workspace that you requested are good.

## Literature

I learned with Real World Haskell
and Brent Yorgey's Typeclassopedia.
*Real World Haskell* will give you a practical introduction to Haskell's
syntax and functional programming, and give you some cunningly written
examples of monadic code. *Typeclassopedia* will give you the
theoretical foundation to understand the progression from functor to
pointed to applicative to monad. Learn how to implement all of the
common monads from scratch. Be competent with both `>>=`

and the `do`

sugaring. `return`

does not
short-circuit execution.

## Hoogle

I Hoogle. Do you
Hoogle? I have Hoogle setup as a keyword shortcut in
Firefox, under the letter `h`. I also have it
locally with `cabal install hoogle`

. Use it
to find what module functions are in, lookup those weird
operators like `>>>`

and `<*>`

,
and discover new functions from type signatures.

## Types

So you got a type error. How do you go about fixing it?

- Do you have an explicit type signature for the top-level? Is it correct? What does Haskell infer if you leave it out?
- Replace parts of your expression with
`undefined`

until it typechecks, then figure out where the mismatch was. - Rewrite the function from scratch. It's short, right?
If you're running into type errors with monadic code, pay close attention to where the

`m`

is in the inputs and outputs of your functions.liftM (a -> b) -> m a -> m b ap m (a -> b) -> m a -> m b =<< (a -> m b) -> m a -> m b $ (m a -> m b) -> m a -> m b return a -> m a - Did you ask #haskell?

## Exercises

I find working through mind-bending problems is a good way to test how well you've figured out a concept and also get intimately familiar with details. Here are some problems that should be done as you work your way through Typeclassopedia.

### Functors

- Implement
`fmap`

for`Either e`

,`((,) e)`

and`((->) e)`

. - Write a function with type signature
`Functor f => (a -> b) -> f (f a) -> f (f b)`

. If you are stuck, try writing the function for a specific instance of functor. Can this type signature be generalized? - What is the type of
`fmap fmap`

? Specify both using`Functor f =>`

and explicitly. Remember that all functions in Haskell are automatically curried. - What is the type of
`fmap fmap fmap`

?

### Pointed

- Implement
`pure`

for`[]`

and`((->) e)`

. - Assuming a well-behaved functor that follows the laws
`fmap id = id`

and`fmap (g . h) = fmap g . fmap h`

, prove that`fmap g . pure = pure . g`

for all definitions of`pure`

. (*Nota bene:*a rigorous treatment of this question may require Wadler's theorems for free, which is not for the lighthearted.)

### Applicative

- What symbols are used for the infix version of
`fmap`

? - Implement
`<*>`

for`Maybe`

,`[]`

and`ZipList`

. - Implement
`<*>`

for`((->) e)`

. This is tricky. - What is the value of
`[(+1), (+2)] <*> [4, 5]`

? - What is the type of
`const <*> id`

? Rewrite this expression in a form that makes this obvious from the applicative law`fmap g x = pure g <*> x`

. - What is the value of
`((+) <*> (+3)) 5?`

- Write
`fmap`

with`pure`

and`<*>`

. - Write
`liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c`

with only`<$>`

and`<*>`

.

## Errors

Errors can be broadly be divided into
two types: pure and impure. Pure errors utilize data types
like `Maybe`

, `Either`

or
`MonadError`

and are used monadically to short-circuit
execution. Impure errors mean that the function
returns "bottom" (a "value" that means the computation cannot
terminate) and possibly have additional semantics attached
to it, such as `error`

(prints string error message)
or asynchronous exceptions.

Pure errors are what you should turn to first when you find yourself in need of some sort of error reporting mechanism. Descriptive pure errors also fall into several categories: some errors are intended to be "caught" and then result in execution flow change, while others are unrecoverable and intended to be passed straight to the user.