Prisms for sum types

I’ve thought that Prism optics are mainly about navigating sum types, but the readily-available examples are about things like going from natural numbers to integers or showing the use of predefined prisms. Is that because defining Prisms for sum types is tedious?

Consider this sum type:

data Fill
  = Solid Color
  | LinearGradient Color Color Percent
  | RadialGradient Color Color Point
  | NoFill

Is there a less cumbersome way to define a Prism for the Solid case than this?

chooseSolidM fill =
  case fill of
    Solid x -> Just x
    _ -> Nothing

solidM = prism' Solid chooseSolidM

… or the variant using Either:

chooseSolidE fill =
  chooseSolidM fill # note fill

solidE = prism Solid chooseSolidE

Sum types are definitely a much better example than those I think - prisms are predominantly used for sum types in my world at least! But no, in PS there isn’t really a more succinct way of describing them. The only tweak I’d suggest is using an anonymous case construct so that it’s only one expression:

_Solid = prism' Solid case _ of
  Solid x -> Just x
  _ -> Nothing

Like the record wildcards case _ of ... essentially means (\x -> case x of ...).

I think there may be a generic lenses library or something that allows you to derive them via generics-rep, but not without a performance penalty, so these kind of definitions are very common.

1 Like

I’ve made a pull request for this explanation of prisms for sum types: https://github.com/marick/purescript-profunctor-lenses/blob/master/examples/src/PrismsForSumTypes.purs

I welcome comments on the pull request: https://github.com/purescript-contrib/purescript-profunctor-lenses/pull/88