Question

Given some data structure with lenses defined, for example:

import Control.Lens

data Thing =
  Thing {
    _a :: String
  , _b :: String
  , _c :: Int
  , _d :: Int
  }

makeLenses ''Thing

And given some function that I want to call using several getters, for example:

fun :: Int -> String -> Int -> String -> Bool
fun = undefined

At the moment, I end up with a lot of ugliness with parens to access each field, for example:

thing = Thing "hello" "there" 5 1

answer = fun (thing^.c) (thing^.a) (thing^.d) (thing^.b)

Given the conciseness of the lens library in most other situations I was hoping for something a little more elegant, but I can't find any combinators that will help this specific case.

Was it helpful?

Solution

Since any lens could be used in either the viewing or the setting "mode", we'll need to at least specify view X for each lens X. But for any lens l :: Lens' a b, view l has a type like a -> b if you translate some of the MonadReader noise.

We can thus get rid of some of the repetition using the Applicative instance for ((->) a).

thing & fun <$> view c <*> view a <*> view d <*> view b
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top