nim_iterator_stream_experiment/optics/plens

Polymorphic lenses from functional programming.

A lens lets one focus on a subpart of a whole (typically a data structure), and manipulate that subpart while keeping the rest of the structure.

A lens is an abstraction of a structure member. Lenses can be chained together to let one see further in the focused structure.

Normal lenses let one modify a structure without changing its type. Polymorphic lenses allow to do so while changing its type.

Modifications of the focused structure can be free of side effects or not. It is up to the lens implementation.

Examples:

Types

MemberReader[S; T] = Reader[S, T]
  Source Edit
MemberUpdater[SR; W; SW] = (state: SR, value: W) -> SW
  Source Edit
PLens[SR; R; W; SW] = object
  reader: MemberReader[SR, R]
  writer: MemberUpdater[SR, W, SW]
  Source Edit

Procs

proc read[SR; R; W; SW](state: SR; lens: PLens[SR, R, W, SW]): R
  Source Edit
proc write[SR; R; W; SW](state: SR; lens: PLens[SR, R, W, SW]; value: W): SW
  Source Edit
proc modify[SR; R; W; SW](state: SR; lens: PLens[SR, R, W, SW]; f: R -> W): SW
  Source Edit

Funcs

func lens[SR; R; W; SW](reader: MemberReader[SR, R]; writer: MemberUpdater[SR, W, SW]): PLens[
    SR, R, W, SW]
  Source Edit
func read[SR; R; W; SW](self: PLens[SR, R, W, SW]): Reader[SR, R]
  Source Edit
func write[SR; R; W; SW](self: PLens[SR, R, W, SW]; value: () -> W): Reader[SR, SW]
  Source Edit
func modify[SR; R; W; SW](self: PLens[SR, R, W, SW]; f: R -> W): Reader[SR, SW]
  Source Edit
func chain[SR; R1; W1; SW; R2; W2](self: PLens[SR, R1, W1, SW];
                             other: PLens[R1, R2, W2, W1]): PLens[SR, R2, W2, SW]
  Source Edit

Templates

template readStateType[SR; R; W; SW; ](X: typedesc[PLens[SR, R, W, SW]]): typedesc[SR]
  Source Edit
template readMemberType[SR; R; W; SW; ](X: typedesc[PLens[SR, R, W, SW]]): typedesc[R]
  Source Edit
template writtenMemberType[SR; R; W; SW; ](X: typedesc[PLens[SR, R, W, SW]]): typedesc[W]
  Source Edit
template writtenStateType[SR; R; W; SW; ](X: typedesc[PLens[SR, R, W, SW]]): typedesc[SW]
  Source Edit
template readStateType[SR; R; W; SW; ](self: PLens[SR, R, W, SW]): typedesc[SR]
  Source Edit
template readMemberType[SR; R; W; SW; ](self: PLens[SR, R, W, SW]): typedesc[R]
  Source Edit
template writtenMemberType[SR; R; W; SW; ](self: PLens[SR, R, W, SW]): typedesc[W]
  Source Edit
template writtenStateType[SR; R; W; SW; ](self: PLens[SR, R, W, SW]): typedesc[SW]
  Source Edit