Optics for accessing list item - Haskell

Welcome to the Functional Programming Zulip Chat Archive. You can join the chat here.

Vincent L

Hi,
I'd like to use optics in a purescript code but I think my question would apply to Haskell.

I have a type data PerformanceAggregate = PerfAgg { cpuSum :: Int, categories :: List PerformanceAggregate}. I added a lens for the cpuSum (_cpuSum) and categories (_categories) field. Obviously I'd like to use an optic to access element in the list, in my case I'm mostly interessed by the first one.

I built an optic _categories . (Lens.ix 0) for this first item in the list. I'm using it with the preview function and it works just fine, returning a Maybe PerformanceAggregate. But updating it is a little more complicated.
What I want is :

  • if there is an element in the list, I want to update it.
  • if there is no element in the list, I want to insert one.

I'd like to know if there is a way to have the 2 bullet points with a single function call. I'm not familiar with prism at all, I don't know what is the equivalent of over for instance, and for the second I don't know if it's possible to add an element a List with the composed optics. I currently call Lens.set _categories and use fromMaybe + List.tailie something quite unelegant.

Torsten Schmits

it doesn't work with over?

Vincent L

you're right, over works, I though it didn't (assuming we needed a preview instead of a view, and a review instead of... a set I guess)

Torsten Schmits

like _categories . at 0 %~ (f :: Maybe a -> Maybe a)

Vincent L

what is the difference between ix and at ?

Torsten Schmits

not sure, I always use at. I think ix is more flexible

Vincent L

it seems however that at is not available in purescript

Vincent L

there is no lens that will append an object if there is no object in a container ?

Torsten Schmits

ah, right. then the specific semantics are probably not that important here

Torsten Schmits

well my impression was that if you get a Nothing in f and return Just, it will append

Vincent L

will give a try. thanks !

Vincent L

actually there is at in purescript too, but not in the module I imported