package Ġopt ik al . opt ics Ċ Ċ import Ġk ategory .* Ċ Ċ /** Ċ Ġ* ĠAn Ġ[ Iso ] Ġdefines Ġan Ġis om orphism Ġbetween Ġa Ġtype ĠS Ġand ĠA : Ċ Ġ* Ġ< pre > Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠ Ġget Ċ Ġ* ĠĠĠĠ Ġ-------------------- > Ċ Ġ* ĠĠ ĠS ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠA Ċ Ġ* ĠĠĠĠ Ġ< -------------------- Ċ Ġ* ĠĠĠĠĠĠĠĠĠ Ġreverse Get Ċ Ġ* Ġ</ pre > Ċ Ġ* ĠA Ġ[ Iso ] Ġis Ġalso Ġa Ġvalid Ġ[ Getter ], Ġ[ Fold ], Ġ[ Lens ], Ġ[ Prism ], Ġ[ Optional ], Ġ[ Traversal ] Ġand Ġ[ Setter ] Ċ Ġ* Ċ Ġ* Ġ@ param ĠA Ġthe Ġsource Ġof Ġa Ġ[ Iso ] Ċ Ġ* Ġ@ param ĠB Ġthe Ġtarget Ġof Ġa Ġ[ Iso ] Ċ Ġ*/ Ċ abstract Ġclass ĠI so < A , ĠB > Ġ{ ĊĊĠĠĠ Ġ/** Ġget Ġthe Ġtarget Ġof Ġa Ġ[ ISO ] Ġ*/ ĊĠĠĠ Ġabstract Ġfun Ġget ( a : ĠA ): ĠB ĊĊĠĠĠ Ġ/** Ġget Ġthe Ġmodified Ġsource Ġof Ġa Ġ[ ISO ] Ġ*/ ĊĠĠĠ Ġabstract Ġfun Ġreverse Get ( b : ĠB ): ĠA ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* Ġcreate Ġan Ġ[ Iso ] Ġbetween Ġany Ġtype Ġand Ġitself . Ġid Ġis Ġthe Ġzero Ġelement Ġof Ġopt ics Ġcomposition , Ġfor Ġall Ġopt ics Ġo Ġof Ġtype ĠO Ġ( e . g . ĠLens , ĠI so , ĠPrism , Ġ... ): ĊĠĠĠĠĠĠĠĠ Ġ* Ġo ĠĠĠĠĠ Ġcompose Iso ĠI so . id Ġ== Ġo ĊĠĠĠĠĠĠĠĠ Ġ* ĠI so . id Ġcompose O ĠĠ Ġo ĠĠĠĠĠĠĠ Ġ== Ġo Ġ( replace Ġcompose O Ġby Ġcompose Lens , Ġcompose Iso , Ġcompose Prism , Ġ...) ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġ< A > Ġid () Ġ= ĠI so < A , ĠA >( :: identity , Ġ:: identity ) ĊĊĠĠĠĠĠĠĠ Ġoperator Ġfun Ġ< A , ĠB > Ġinvoke ( get : Ġ( A ) Ġ-> Ġ( B ), Ġreverse Get : Ġ( B ) Ġ-> ĠA ) Ġ= Ġobject Ġ: ĠI so < A , ĠB >() Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġget ( a : ĠA ): ĠB Ġ= Ġget ( a ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġreverse Get ( b : ĠB ): ĠA Ġ= Ġreverse Get ( b ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** Ġreverse Ġa Ġ[ Iso ]: Ġthe Ġsource Ġbecomes Ġthe Ġtarget Ġand Ġthe Ġtarget Ġbecomes Ġthe Ġsource Ġ*/ ĊĠĠĠ Ġfun Ġreverse (): ĠI so < B , ĠA > Ġ= Ġobject Ġ: ĠI so < B , ĠA >() Ġ{ ĊĠĠĠĠĠĠĠ Ġ/** Ġget Ġthe Ġtarget Ġof Ġa Ġ[ Iso ] Ġ*/ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġget ( a : ĠB ): ĠA Ġ= Ġreverse Get ( a ) ĊĊĠĠĠĠĠĠĠ Ġ/** Ġget Ġthe Ġmodified Ġsource Ġof Ġa Ġ[ Iso ] Ġ*/ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġreverse Get ( b : ĠA ): ĠB Ġ= Ġget ( b ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** Ġmodify Ġpol ym orph ically Ġthe Ġtarget Ġof Ġa Ġ[ Iso ] Ġwith Ġa Ġfunction Ġ*/ ĊĠĠĠ Ġinline Ġfun Ġmodify ( cross inline Ġf : Ġ( B ) Ġ-> ĠB ): Ġ( A ) Ġ-> ĠA Ġ= Ġ{ Ġa Ġ-> Ġreverse Get ( f ( get ( a ))) Ġ} ĊĊĠĠĠ Ġ/** Ġmodify Ġpol ym orph ically Ġthe Ġtarget Ġof Ġa Ġ[ Iso ] Ġwith Ġa ĠFun ctor Ġfunction Ġ*/ ĊĠĠĠ Ġinline Ġfun Ġ< re ified ĠF > Ġmodify F ( FF : ĠFun ctor < F > Ġ= Ġfunctor (), Ġf : Ġ( B ) Ġ-> ĠH K < F , ĠB >, Ġa : ĠA ): ĠH K < F , ĠA > Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFF . map ( f ( get ( a )), Ġthis :: reverse Get ) ĊĊĠĠĠ Ġ/** Ġset Ġpol ym orph ically Ġthe Ġtarget Ġof Ġa Ġ[ Iso ] Ġwith Ġa Ġvalue Ġ*/ ĊĠĠĠ Ġfun Ġset ( b : ĠB ): Ġ( A ) Ġ-> Ġ( A ) Ġ= Ġ{ Ġreverse Get ( b ) Ġ} ĊĊĠĠĠ Ġ/** Ġcompose Ġa Ġ[ Iso ] Ġwith Ġa Ġ[ Iso ] Ġ*/ ĊĠĠĠ Ġin fix Ġfun Ġ< C > Ġcompose Iso ( other : ĠI so < B , ĠC >): ĠI so < A , ĠC > Ġ= ĠI so ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ{ Ġa Ġ-> Ġother . get ( get ( a )) Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis :: reverse Get Ġcompose Ġother :: reverse Get ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġ/** Ġview Ġa Ġ[ Iso ] Ġas Ġa Ġ[ Optional ] Ġ*/ ĊĠĠĠ Ġfun Ġas Optional (): ĠOptional < A , ĠB > Ġ= ĠOptional ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ{ Ġa Ġ-> ĠOption . Some ( get ( a )) Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis :: set ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġ/** Ġview Ġa Ġ[ Iso ] Ġas Ġa Ġ[ Prism ] Ġ*/ ĊĠĠĠ Ġfun Ġas Prism (): ĠPrism < A , ĠB > Ġ= ĠPrism ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ{ Ġa Ġ-> ĠEither . Right ( get ( a )) Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis :: reverse Get ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġ/** Ġview Ġa Ġ[ Iso ] Ġas Ġa Ġ[ Lens ] Ġ*/ ĊĠĠĠ Ġfun Ġas Lens (): ĠLens < A , ĠB > Ġ= ĠLens ( this :: get , Ġthis :: set ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġview Ġa Ġ[ Iso ] Ġas Ġa Ġ[ Getter ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġas Getter (): ĠGetter < A , ĠB > Ġ= ĠGetter ( this :: get ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠView Ġan Ġ[ Iso ] Ġas Ġa Ġ[ Setter ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġas Setter (): ĠSetter < A , ĠB > Ġ= ĠSetter ( this :: modify ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠView Ġa Ġ[ Iso ] Ġas Ġa Ġ[ Traversal ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġas Traversal (): ĠTra versal < A , ĠB > Ġ= Ġobject Ġ: ĠTra versal < A , ĠB >() Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġ< F > Ġmodify FI ( FA : ĠApplic ative < F >, Ġf : Ġ( B ) Ġ-> ĠH K < F , ĠB >, Ġa : ĠA ): ĠH K < F , ĠA > Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFA . map ( f ( get ( a )), Ġthis @ Iso :: reverse Get ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠView Ġa Ġ[ Iso ] Ġas Ġa Ġ[ Fold ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġas Fold (): ĠFold < A , ĠB > Ġ= Ġobject Ġ: ĠFold < A , ĠB >() Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġ< R > Ġfold Map I ( M : ĠMon oid < R >, Ġa : ĠA , Ġf : Ġ( B ) Ġ-> ĠR ): ĠR Ġ= Ġf ( get ( a )) ĊĠĠĠ Ġ} Ċ }