scalahaskellfunctional-programminglensesmonocle-scala

Is there a van Laarhoven representation of `Optional`


Many types of optics have a van Laarhoven representation.

For example, a Lens of type Lens s t a b can be represented as:

 Functor f => (a -> f b) -> s -> f t

Similarly a Traversal, can be represented in a similar way, swapping the Functor constraint for Applicative:

 Applicative f => (a -> f b) -> s -> f t

Several optics frameworks, such as Monocle and Arrow define a type called Optional.

In Monocle's Optics heirarchy Optional fits between Lens and Traversal

As I understand it: If a Traversal is like a Lens that may have zero to many targets, then an Optional is like a Lens that may have zero to one targets.

In Monocle, Optional is defined as a pair of functions:

getOrModify :: s -> Either t a 
set :: (b, s) -> t

Comments in the Monocle source code suggest that it's also possible to represent an Optional "as a weaker PLens and weaker PPrism"

Is it possible to represent an Optional as a van Laarhoven function?


Solution

  • There would be a way to represent it if the Functor/Applicative/Monad hierarchy were more fine-grained. In particular:

    class Functor f => Pointed f where
        pure :: a -> f a
    
    type Optional s t a b = forall f. Pointed f => (a -> f b) -> s -> f t
    

    Note that the type would probably be named Affine in the lens library if that was neatly in the class hierarchy.