Module

Data.Lens.Prism

Package
profunctor-lenses
Repository
purerl/purescript-profunctor-lenses

Prisms are used for selecting cases of a type, most often a sum type. Consider this:

data Fill -- think of a paint program filling a shape
  = NoFill
  | Solid Color
  | ...

A prism that focuses on Solid fills could be written like this:

solidFocus :: Prism' Fill Color
solidFocus = prism' Solid case _ of
  Solid color -> Just color
  _ -> Nothing

... and used like this:

preview solidFocus (Solid Color.white) == Just Color.white
preview solidFocus NoFill == Nothing

is solidFocus (Solid Color.white) == true

review can be used to go from a Color to a Fill:

review solidFocus Color.white == Solid Color.white

For more information, see PrismsForSumTypes.purs in the examples/src directory.


A well-behaved Prism will follow these laws:

review-preview: preview retrieves what review creates. Equationally:

review prism >>> preview prism ≡ Just

An example:

Color.white # review solidFocus # preview solidFocus
  == Just Color.white

preview-review: If preview retrieves something, review can create the original from that something. Equationally:

if preview prism s ≡ Just a then review prism a ≡ s

An example:

Solid Color.white # preview solidFocus <#> review solidFocus
  == Solid Color.white

#prism' Source

prism' :: forall a s. (a -> s) -> (s -> Maybe a) -> Prism' s a

Create a Prism from a constructor and a matcher function that produces a Maybe:

solidFocus :: Prism' Fill Color
solidFocus = prism' Solid case _ of
  Solid color -> Just color
  _ -> Nothing

#prism Source

prism :: forall b a t s. (b -> t) -> (s -> Either t a) -> Prism s t a b

Create a Prism from a constructor and a matcher function that produces an Either:

solidFocus :: Prism' Fill Color
solidFocus = prism Solid case _ of
  Solid color -> Right color
  anotherCase -> Left anotherCase

Note: The matcher function returns a result wrapped in Either t to allow for type-changing prisms in the case where the input does not match.

#only Source

only :: forall a. Eq a => a -> Prism a a Unit Unit

only focuses not just on a case, but a specific value of that case.

solidWhiteFocus :: Prism' Fill Unit
solidWhiteFocus = only $ Solid Color.white

is      solidWhiteFocus (Solid Color.white) == true
preview solidWhiteFocus (Solid Color.white) == Just unit
review  solidWhiteFocus unit                == Solid Color.white

Note: only depends on Eq. Strange definitions of (==) (for example, that it counts any Fill as being equal to Solid Color.white) will create a prism that violates the preview-review law.

#nearly Source

nearly :: forall a. a -> (a -> Boolean) -> Prism' a Unit

nearly is a variant of only. Like only, nearly produces a prism that matches a single value. Unlike only, it uses a predicate you supply instead of depending on class Eq:

solidWhiteFocus :: Prism' Fill Unit
solidWhiteFocus = nearly (Solid Color.white) predicate
  where
    predicate candidate =
      color.toHexString == Color.white.toHexString

#review Source

review :: forall b a t s. Review s t a b -> b -> t

Create the "whole" corresponding to a specific "part":

review solidFocus Color.white == Solid Color.white

#is Source

is :: forall r b a t s. HeytingAlgebra r => APrism s t a b -> s -> r

Ask if preview prism would produce a Just.

#isn't Source

isn't :: forall r b a t s. HeytingAlgebra r => APrism s t a b -> s -> r

Ask if preview prism would produce a Nothing.

#matching Source

matching :: forall b a t s. APrism s t a b -> s -> Either t a

#clonePrism Source

clonePrism :: forall b a t s. APrism s t a b -> Prism s t a b

#withPrism Source

withPrism :: forall r b a t s. APrism s t a b -> ((b -> t) -> (s -> Either t a) -> r) -> r

Re-exports from Data.Lens.Types

#Review' Source

type Review' s a = Review s s a a

#Review Source

type Review s t a b = Optic Tagged s t a b

A review.

#Prism' Source

type Prism' s a = Prism s s a a

#Prism Source

type Prism s t a b = forall p. Choice p => Optic p s t a b

A prism.

#APrism' Source

type APrism' s a = APrism s s a a

#APrism Source

type APrism s t a b = Optic (Market a b) s t a b