On this page:
prism?
make-prism
prism-absent
prism-absent?
2.5.1 Prism Operations
prism-project
prism-inject
prism-compose
2.5.2 Library Prisms
string-number-prism
guard-prism
2.5.3 Prism Generic Interface
gen:  prism
8.15.0.2

2.5 Prisms🔗ℹ

 (require ocular-patdown/optics/prism)
  package: ocular-patdown

A prism is an optic that is like an isomorphism, but can be partial in one direction. In terms of foci, it can have zero or one. It is useful for dealing with subtypes, or situations where you can convert from A to B, but not always from B to A.

Examples:

All isomorphisms are prisms, but not all prisms are isomorphisms.

All prisms are traversals, but not all traversals are prisms.

procedure

(prism? val)  boolean?

  val : any/c
Predicate for prisms. Recognizes implementers of gen:prism.

procedure

(make-prism project inject)  prism?

  project : (-> any/c (or/c any/c prism-absent?) any/c)
  inject : (-> any/c any/c)
Constructor for prisms. project takes in a target and returns the focus if there is one, or (prism-absent) otherwise. inject takes in a focus and returns a target.

Example:
> (define my-string-number-prism
    (make-prism
      (lambda (str) (or (string->number str) (prism-absent)))
      number->string))

There are a few laws that prisms should obey:
  • Projecting after injecting should yield the injected focus.

    (equal? (project (inject focus)) focus)

  • If the target has a focus, injecting after projecting should yield the target.

    (equal? (inject (project target)) target)

These laws are the same as the isomorphism laws (see make-iso) when there is a focus. In other words, project and inject must be inverse functions of each other when there is a focus.

procedure

(prism-absent)  prism-absent?

Constructs a value representing the absence of a focus in a prism.

procedure

(prism-absent? val)  boolean?

  val : any/c
Predicate for prism-absent.

2.5.1 Prism Operations🔗ℹ

procedure

(prism-project prism target [failure-result])  any/c

  prism : prism?
  target : any/c
  failure-result : (or/c any/c (-> any/c))
   = (lambda () (error ...))
Get the focus of target under prism if there is one, and use failure-result otherwise.

failure-result is either a value or a zero-argument procedure that returns a value.

procedure

(prism-inject prism focus)  any/c

  prism : prism?
  focus : any/c
Get the target from focus under prism.

procedure

(prism-compose prism ...)  prism?

  prism : prism?
Like optic-compose, but for prisms.

2.5.2 Library Prisms🔗ℹ

Prism between strings and numbers.

procedure

(guard-prism predicate)  prism?

  predicate : (-> any/c boolean?)
Prism that has a focus if (predicate target) is true.

2.5.3 Prism Generic Interface🔗ℹ

syntax

gen:prism

Generic interface for prisms.

Example:
> (struct make-prism (project inject)
    #:methods gen:prism
    [(define (prism-project prism target [failure-result default-failure-result])
       (let ([focus ((make-prism-project prism) target)])
         (if (prism-absent? focus)
             (if (procedure? failure-result)
                 (failure-result)
                 failure-result)
             focus)))
     (define (prism-inject prism focus)
       ((make-prism-inject prism) focus))])