<!--

> {-# LANGUAGE CPP #-}

-->
<h2><a name="ixset_lens">IxSet and Data.Lens</a></h2>
<p class="warning">To use IxSet with Data.Lens you will need to install the optional <kbd>data-lens-ixset</kbd>, <kbd>data-lens-template</kbd>, and <kbd>data-lens-fd</kbd> packages.</p>

It is very common to use records and nested records with `IxSet` and `acid-state`. Unfortunately, Haskell record support is pretty pitiful at the moment. People have been proposing improvements for years -- but until some proposals get implemented we need some way to make life more pleasant. One popular solution is the <kbd>data-lens</kbd> library.

At first, lenses sound like they must be something really crazy or difficult -- like `Arrows` but even worse! But, in reality, lenses are pretty simple. Lenses are really just some new syntax to make it easy to compose getters, setters, and modifiers.

It can take a bit of practice to get used to lenses. But, fortunately, using them is completely optional -- so if they are not your thing, you don't have to use them. In this tutorial we will start with a general introduction to using lenses, and then finish up with showing how to use them with `IxSet` and `acid-state`.

<div class="code">

> {-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving
>   , OverloadedStrings, TemplateHaskell #-}

> module Main where
>
> import Control.Applicative (pure)
> import Control.Category   ((.), (>>>))
> import Control.Comonad.Trans.Store.Lazy
> import Data.Acid          (Update)
> import Data.Data          (Data, Typeable)
> import Data.IxSet         (IxSet, Indexable(empty), (@=), fromList, ixFun, ixSet)
> import Data.Lens          (Lens, (^$), (^.), (^=), (^%=), (^%%=), (^+=), (%=), getL, setL, modL)
> import Data.Lens.Template (makeLens)
> import Data.Lens.IxSet    (ixLens)
> import Data.Lens.Partial.Common (PartialLens(..), maybeLens, totalLens)
> import Data.SafeCopy      (SafeCopy, base, deriveSafeCopy)
> import Data.Text          (Text)
> import Prelude            hiding ((.))

</div>

<h3><a name="ixset_lens_creating">Creating Lenses</a></h3>

We start by defining a simple `User` record which contains some nested records: 

<div class="code">

> newtype UserId = UserId { _userInt :: Integer } 
>     deriving (Eq, Ord, Data, Typeable, SafeCopy, Show)
>
> $(makeLens ''UserId)
>
> data Name = Name 
>     { _nickName  :: Text
>     , _firstName :: Text
>     , _lastName  :: Text
>     }
>     deriving (Eq, Ord, Data, Typeable, Show)
>
> $(deriveSafeCopy 0 'base ''Name)
> $(makeLens ''Name)
>
> data User = User
>     { _userId :: UserId
>     , _name   :: Name
>     }
>     deriving (Eq, Ord, Data, Typeable, Show)
>
> $(deriveSafeCopy 0 'base ''User)
> $(makeLens ''User)
>
> -- | example user
> stepcut :: User
> stepcut = 
>     User { _userId = UserId 0
>          , _name   = Name { _nickName  = "stepcut"
>                           , _firstName = "Jeremy"
>                           , _lastName  = "Shaw"
>                           }
>          }

</div>

There are two things to notice:

 1. the field names all start with an underscore. That is because new helper functions will be generated that do not contain the underscore.

 2. there is a template haskell call `$(makeLens ''Type)`. This template haskell call generates lens functions based on the fields in the record. If you want to see what it is actually generating you can compile with <kbd>-ddump-splices</kbd>. Here is one of the lenses generated by `$(makeLens ''User)`:

<div class="code">
#ifdef HsColour
> userId :: Lens User UserId
> userId = lens _userId (\ uid user -> user { _userId = uid })
#endif
</div>

We see that a lens is basically just a getter function and a setter function. In this case, a getter function that can get a `UserId` from a `User` and a setter function that can set the `UserId` in a `User`.

<h3><a name="ixset_lens_getters">Getters</a></h3>

There are two getter operators: one for left-to-right composition and one for right-to-left composition. There is also a getter function. They all serve the same purpose -- it's just a matter of taste which you use.

The first operator is:

<div class="code">
#ifdef HsColour
> (^$), (^$!)  :: Lens a b -> a -> b
#endif
</div>

There are two variations `^$` is the normal version. `^$!` does the same thing except that internally it uses `$!` to more strictly evaluate the calculation. It is used like this:

<div class="code">

> stepcutFirstName :: Text
> stepcutFirstName = firstName ^$ name ^$ stepcut

</div>

Notice that `^$` is used a lot like `$`. In fact we could write this with out lenses at all like this:

<div class="code">

> stepcutFirstName2 :: Text
> stepcutFirstName2 = _firstName $ _name $ stepcut

</div>

The other getter operator is:

<div class="code">
#ifdef HsColour
> (^.), (^!) :: a -> Lens a b -> b
#endif
</div>

Where `^.` is the normal version and `^!` is the stricter version. 

We can use it like this:

<div class="code">

> stepcutFirstName3 :: Text
> stepcutFirstName3 = (stepcut ^. name) ^. firstName

</div>

So, here `^.` is meant to act like a field accessor in a traditional object oriented language where we would write:

<div class="code">
#ifdef HsColour
stepcut.name.firstName
#endif
</div>

Finally, we have the `getL` function:

<div class="code">
#ifdef HsColour
> getL :: Lens a b -> a -> b
#endif
</div>

`getL` is useful for creating partially applied functions. For
example, we can create a function that gets a `User`'s first name like
this:

<div class="code">

> getFirstName :: User -> Text
> getFirstName = getL firstName . getL name 

</div>

<h3><a name="ixset_lens_category"><kbd>Lens</kbd> is an instance of <code>Category</code></a></h3>

`Lens` is an instance of `Category`. That means we can use the `.` operator from `Category` to compose lenses.

The normal `.` looks like this:

<div class="code">
#ifdef HsColour
> -- | as defined in 'Prelude'
> (.) :: (b -> c) -> (a -> b) -> a -> c
#endif
</div>

But `.` can be generalized to work for any `Category` like this:

<div class="code">
#ifdef HsColour
> -- | as defined in 'Control.Category'
> (.)  :: (Category cat) => cat b c -> cat a b -> cat a c
#endif
</div>

If you look closely at the imports at the top, you will notice that we hide `.` from the `Prelude` and imported the version from `Control.Category` instead. Now we can write this:

<div class="code">

> stepcutFirstName4 :: Text
> stepcutFirstName4 = firstName . name ^$ stepcut

</div>

Which looks very similar to the non-lens version:

<div class="code">

> stepcutFirstName5 :: Text
> stepcutFirstName5 = _firstName . _name $ stepcut

</div>

If we look at the type of `firstName . name` we see that we just get a lens that goes straight from `User` to `Text`:

<div class="code">
#ifdef HsColour
*Main> :t firstName . name<br>
firstName . name :: Lens User Text
#endif
</div>

<h3><a name="ixset_lens_setters">Setters</a></h3>

Next we have the setter operator. This is where lenses start to shine. The setter operator is:

<div class="code">
#ifdef HsColour
> (^=), (^!=) :: Lens a b -> b -> a -> a
#endif
</div>

Once again we have a lazier version `^=` and a stricter version `^!=`.

We can use it to update the `UserId` in the `User` type like this:

<div class="code">

> setUserId :: (User -> User)
> setUserId = userId ^= (UserId 1)

</div>

So, we see that `^=` is used to create an update function. If we wanted to update a specific record we could write it like this:

<div class="code">

> setStepcutUserId :: User
> setStepcutUserId = userId ^= (UserId 1) $ stepcut

</div>

Instead of the infix operator we could instead `setL`:

<div class="code">
#ifdef HsColour
> setL :: Lens a b -> b -> a -> a
#endif
</div>

as such:

<div class="code">

> setUserId' :: (User -> User)
> setUserId' = setL userId (UserId 1)

</div>


<h3><a name="ixset_lens_modifiers">Modifiers</a></h3>

Often times we want to apply a function to transform an existing value rather than just setting a new value. For that we use:

<div class="code">
#ifdef HsColour
> (^%=), (^!%=) :: Lens a b -> (b -> b) -> a -> a
#endif
</div>

For example, we can increment the `Integer` inside the `UserId` like so:

<div class="code">

> incUserId :: UserId -> UserId
> incUserId = (userInt ^%= succ)

</div>

Or we could use the `modL` function:

<div class="code">
#ifdef HsColour
> modL :: Lens a b -> (b -> b) -> a -> a
#endif
</div>

<div class="code">

> incUserId' :: UserId -> UserId
> incUserId' = modL userInt succ

</div>


<h3><a name="ixset_lens_nested">Updating Nested Records</a></h3>

If we want to update a nested record then need to combine setters and modifiers. For example, we can update the `nickName` like this:

<div class="code">

> setNick :: Text -> (User -> User)
> setNick nick = name ^%= (nickName ^= nick)

</div>

That says we want to modify the `name` field of a `User` by setting the `nickName` of the `Name`.

Another option would be to leverage the `Category` instance for `Lens` and use the `.` operator:

<div class="code">

> setNick2 :: Text -> (User -> User)
> setNick2 newNick = (nickName . name) ^= newNick

</div>

However, I find that a bit confusing to read, because the field names are listed right-to-left, but the overall flow of that line is left-to-right. If we want a consistent left-to-right feel we can use the `>>>` operator:

<div class="code">
#ifdef HsColour
> (>>>) :: Control.Category.Category cat => cat a b -> cat b c -> cat a c
#endif
</div>

<div class="code">

> setNick3 :: Text -> (User -> User)
> setNick3 newNick = (name >>> nickName) ^= newNick

</div>

<h3><a name="ixset_lens_other_modifiers">Other Modifiers</a></h3>

The lens library also provides some operators that encapsulate common updates such as addition and subtraction. For example,

<div class="code">

> addToUserId :: Integer -> (UserId -> UserId)
> addToUserId i = (userInt ^+= i)

</div>

<h3><a name="ixset_lens_ixset">Lens for <code>IxSet</code></a></h3>

So far we have examined updating fields in a record. But there is no reason why a lens need to be limited to a record. The idea can be used with just about any type where we have the ability to focus on a single element. We can create a lens for an `IxSet` by using this `ixLens` function:

<div class="code">
#ifdef HsColour
> ixLens :: (Typeable key, Indexable a, Typeable a, Ord a) => key -> Lens (IxSet a) (Maybe a)
#endif
</div>

For records, the names of the fields are known at compile time, so we were able to automatically create helper functions like `userId`, `name`, etc, to address those fields. For an `IxSet` we generally want to address some value by a key that is determined at runtime, so we can not automatically generate helper functions.

First we need an `Indexable User` instance:

<div class="code">

> instance Indexable User where
>     empty = ixSet [ ixFun $ \u -> [ userId ^$ u ]
>                   ]

</div>

And then we will add the `IxSet` to a state record:

<div class="code">

> data UserState = UserState 
>     { _nextUserId :: UserId
>     , _users      :: IxSet User
>     }
>     deriving (Eq, Ord, Data, Typeable, Show)
>
> $(deriveSafeCopy 0 'base ''UserState)
> $(makeLens ''UserState)
>
> userState :: UserState
> userState = 
>     UserState { _nextUserId = UserId 1
>               , _users      = fromList [ stepcut ]
>               }
>

</div>

<h3><a name="ixset_lens_getter">Using a getter with <code>IxSet</code></a></h3>

It is not a bad idea to define an alias for `ixLens` that has a more meaningful name and a more explicit type:

<div class="code">

> user :: (Typeable key) => key -> Lens (IxSet User) (Maybe User)
> user = ixLens

</div>

That will help make it easier to read the code, and will make type errors more readable.

Now we can extract the `User` with `UserId 0` from `userState`:

<div class="code">

> user0 :: Maybe User
> user0 = user (UserId 0) ^$ users ^$ userState

</div>

<h3><a name="ixset_lens_insert">Inserting an element into an <code>IxSet</code></a></h3>

We can use the setter operator to add a new record to an `IxSet`:

<div class="code">

> addUserId1 :: UserState
> addUserId1 = 
>     let stepcut1 = userId ^= (UserId 1) $ stepcut -- create a duplicate of the stepcut 
>                                                   -- record but with 'UserId 1'
>     in (users ^%= user (userId ^$ stepcut1) ^= (Just stepcut1)) userState

</div>

So, there is something a little tricky going on here. Under the hood,
we are using `updateIx` to insert the record. In this case, we are
updating the non-existing record for `UserId 1`. 

An `updateIx` is performed by deleting the old record (if it exists) and inserting
the new one. However, the key used to delete the old record may not
match the key in the new record we are inserting. For example, if we
did:

<div class="code">

> addUserId1' :: UserState
> addUserId1' = 
>     let stepcut1 = userId ^= (UserId 1) $ stepcut -- create a duplicate of the stepcut 
>                                                   -- record but with 'UserId 1'
>     in (users ^%= user (UserId 0) ^= (Just stepcut1)) userState

</div>

That would delete the existing `UserId 0` record and add a `UserId 1` record instead. It would *not* insert the `stepcut1` record as `UserId 0`.

<h3><a name="ixset_lens_delete">Deleting an element from an <code>IxSet</code></a></h3>

We can delete an element from an `IxSet` by updating it with `Nothing`.

<div class="code">

> deleteUserId0 :: UserState
> deleteUserId0 = (users ^%= user (UserId 0) ^= Nothing) userState

</div>

<h3><a name="ixset_lens_setter">Using a modifier with <code>IxSet</code></a></h3>

Here we update the `nickName` for `UserId 0`:

<div class="code">

> changeNick :: UserState
> changeNick = (users ^%= user (UserId 0) ^%= fmap (name ^%= (nickName ^= "stepkut"))) userState

</div>

In a traditional imperative language we write changeNick something like:

<div class="code">

changeNick() { userState.users[0].name.nickName = "stepkut"; }

</div>

Looking at the two, you can see the similarity, even if the syntax is not as nice.

One important things to note is that the `ixLens` returns a `Maybe` value since we might request a non-existent `UserId`. Here we use `fmap` to set the nick inside the `Maybe` value. However, that means that for a non-existent `UserId` the update silently does nothing. Sometimes that is ok, but if not, then you will need to take a different approach.

We can also try to use `>>>`  instead of all those `^%=`, but the `fmap` is a bit troublesome:

<div class="code">

> changeNick2 :: UserState
> changeNick2 = ((users >>> user (UserId 0)) ^%= fmap ((name >>> nickName) ^= "stepkut")) userState

</div>

Additionally, it seems like `^%=` binds too tightly and so we need some extra `( )` to keep things happy.

<h3><a name="ixset_partial_lens">Using `partial-lens` with <code>IxSet</code></a></h3>

The <a href="http://hackage.haskell.org/package/partial-lens">`partial-lens` package</a> attempts to address the `fmap` problem that we saw in the last section. A `partial-lens` is similar to a `lens` but allows for the fact that the lens may not always be able to produce a value:

<div class="code">
#ifdef HsColour
> newtype PartialLens a b = PLens (a -> Maybe (Store b a))
#endif
</div>

However, it seems a bit awkward to use `partial-lens` at the moment. To use a normal lens with need to convert it to a partial lens using `totalLens`:

<div class="code">
#ifdef HsColour
> totalLens :: Lens a b -> PartialLens a b
#endif
</div>

Additionally, `partial-lens` lacks the `MonadState` interaction that we will examine in the next section (aka, `partial-lens-fd`). But, hopefully these issues will be resolved in the future.

We can turn our `ixLens` into a partial lens like this:

<div class="code">

> -- | note: `setPL` does not insert into an `IxSet` it only modifies a 
> -- value if the key already exists in the map
> ixPLens :: (Typeable key, Ord a, Typeable a, Indexable a) => key -> PartialLens (IxSet a) a
> ixPLens key = maybeLens . totalLens (ixLens key)

</div>

See the <a href="http://hackage.haskell.org/package/partial-lens">haddock page</a> for `partial-lens` for more information. Using `partial-lens` is very similar to a normal lens.

<h3><a name="ixset_lens_setter">Using a setter and modifier with <code>IxSet</code> in an <kbd>acid-state</kbd> event</a></h3>

If we are using `IxSet` with `acid-state`, we can use a special version of the modifier operator that automatically does the `get`/`put` for us:

<div class="code">
#ifdef HsColour
> (%=) :: (MonadState a m) => Lens a b -> (b -> b) -> m b
#endif
</div>

Note that this version of `%=` was imported from `Data.Lens` which comes from the `data-lens-fd` package. There are similar functions in `Data.Lens.Strict` and `Data.Lens.Lazy` but they do not have the right type. 

We can now make `changeNick` into an `Update` event like this:

<div class="code">

> changeNick' :: Update UserState (IxSet User)
> changeNick' = users %= user (UserId 0) ^%= fmap (name ^%= (nickName ^= "stepkut"))

</div>

All we did was change the first `^%=` to `%=`. This works because `Update` is an instance of `MonadState`.


`data-lens-fd` provides a few other functions that you can use to get, set, and modify the state in an `Update` or `Query` event. Check out the <a href='http://hackage.haskell.org/package/data-lens-fd'> haddock documentation for data-lens-fd</a>.

<p class="source-code">[Source code for the app is <a href="IxSetDataLens.hs">here.</a>]</p>

