fn :: Int -> Int
fn x = x + 1
fnM :: State Int ()
fnM = modify (+1)
This is how a canonical record definition in Haskell looks like.
data MyRecord = MyRecord { x :: Int }
fnT :: MyRecord -> MyRecord
fnT a = a { x = x a + 1 }
fnTM :: State MyRecord ()
fnTM = modify \a -> a { x = x a + 1 }
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
&
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)
fnML :: State MyRecord ()
fnML :: x %= (+1)