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.

有帮助吗?

解决方案

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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top