lens-like with get and optional set

24 views
Skip to first unread message

Matthew Pocock

unread,
Jul 24, 2016, 8:32:37 PM7/24/16
to scala-user
Hi,

I'm trying to replace a load of boring but brittle code with lenses. However, I can't find quite the abstraction. I've been using scalaz, but can switch to another library if it works.

Anyway, the operations I need are:

a get with the type: A => B
a set with the type: A => Option[B => A]

So, a getter, and an optional setter. If it's necessary, I can live with an optional getter. I found PLens, but that seems to have an optional getter, with a setter defined whenever the getter is. I need something were the set may not be defined even if the get is.

As an example, I need to be able to 'get' the size of a collection, but obviously, there would be no setter. On the other hand, given a list, I need to be able to get the value at an index, and set it, or perhaps splice in a sub-list at that index.

Thanks,
Matthew

--
Dr Matthew Pocock
Turing ate my hamster LTD

Integrative Bioinformatics Group, School of Computing Science, Newcastle University

skype: matthew.pocock
tel: (0191) 2566550

Oliver Ruebenacker

unread,
Jul 25, 2016, 3:41:14 AM7/25/16
to Matthew Pocock, scala-user

     Hello,

  Sorry, I don't understand the signature of your setter, could you explain?

     Best, Oliver

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Oliver Ruebenacker
Senior Software Engineer, Diabetes Portal, Broad Institute

Matthew Pocock

unread,
Jul 25, 2016, 4:19:23 AM7/25/16
to Oliver Ruebenacker, scala-user
Hi Oliver,

So lens abstracts the idea of a property in some structure, with a get and set operation to get and set that property value within the structure. The get and set can be derived from a doGet and doSet operation:

Lens[A, B] from (doGet: A => B, doSet: A => B => A)

In a PLens, the getter is optional. Some instances of A may have that property, others may not.

PLens[A, B] from (doGet: A => Option[B], doSet: A => B => A)

Obviously, if get is None, then when you come to set, you have nothing to work with, so set is not defined if get is not defined.

What I need is either:

OLens[A, B] from (doGet: A => B, doSet: A => Option[B => A])

or

POLens[A, B] from (doGet: A => Option[B], doSet: A => Option[B => A])

This generalises the idea of a property that may be read-only, or may be read-write. For an instance of A where the property is read-write, doSet returns Some[B => A]. For an instance where it is read-only, it returns None.

So a List[String] has a property size, which is read-only. This would have
OLens[List[String], Int] from (doGet = _.size, doSet = _ => None)

However, a field in a case-class is read-write. This would have

OLense[MyCc, F] from (doGet = _.aField, doSet = cc => Some((f: F) => cc.copy(aField = f)))

Does that help?

Matthew
Reply all
Reply to author
Forward
0 new messages