Skip to content

Instantly share code, notes, and snippets.

@bananu7
Last active August 29, 2015 14:15
Show Gist options
  • Save bananu7/7a33a9ba8c5f76faf6fe to your computer and use it in GitHub Desktop.
Save bananu7/7a33a9ba8c5f76faf6fe to your computer and use it in GitHub Desktop.
Cheat sheet - state in haskell

Simple, opaque/plain state

A regular function

fn :: Int -> Int
fn x = x + 1

A monad with state used directly

fnM :: State Int ()
fnM = modify (+1)

A record state

Traditional

This is how a canonical record definition in Haskell looks like.

data MyRecord = MyRecord { x :: Int }

Function

fnT :: MyRecord -> MyRecord
fnT a = a { x = x a + 1 }

Monad

fnTM :: State MyRecord ()
fnTM = modify \a -> a { x = x a + 1 }

Lens

For a lens-compatible record, we need a bit more boilerplate. The TemplateHaskell extension needs to be enabled, so that makeLenses function can use a quoted type to perform reflective code generation.

We can of course write all of the accessors manually, but that just ends up being even more boilerplate

{-# LANGUAGE TemplateHaskell #-}

data MyRecord = MyRecord { _x :: Int }
makeLenses ''MyRecord

Function

& is simply defined as flip ($). This is to make the following a bit more natural

fnL :: MyRecord -> MyRecord
fnL a = a & x %~ (+1)

That being said, a type of x %~ (+1) is of course MyRecord, and the function can be written point-free as:

fnL = x %~ (+1)

Monad

fnML :: State MyRecord ()
fnML :: x %= (+1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment