package Ġarrow . opt ics . test . l aws Ċ Ċ import Ġarrow . core . compose Ċ import Ġarrow . core . identity Ċ import Ġarrow . opt ics . Lens Ċ import Ġarrow . core . test . l aws . Law Ċ import Ġarrow . core . test . l aws . equal Under The Law Ċ import Ġio . kot est . property . Ar b Ċ import Ġio . kot est . property . ar bitrary . constant Ċ import Ġio . kot est . property . check All Ċ Ċ object ĠLens L aws Ġ{ ĊĊĠ Ġfun Ġ< A , ĠB > Ġlaws ( ĊĠĠĠ Ġlens Gen : ĠA rb < Lens < A , ĠB >>, ĊĠĠĠ Ġa Gen : ĠA rb < A >, ĊĠĠĠ Ġb Gen : ĠA rb < B >, ĊĠĠĠ Ġfunc Gen : ĠA rb <( B ) Ġ-> ĠB >, ĊĠĠĠ Ġeq a : Ġ( A , ĠA ) Ġ-> ĠBoolean Ġ= Ġ{ Ġa , Ġb Ġ-> Ġa Ġ== Ġb Ġ}, ĊĠĠĠ Ġeq b : Ġ( B , ĠB ) Ġ-> ĠBoolean Ġ= Ġ{ Ġa , Ġb Ġ-> Ġa Ġ== Ġb Ġ} ĊĠ Ġ): ĠList < Law > Ġ= ĊĠĠĠ ĠlistOf ( ĊĠĠĠĠĠ ĠLaw (" Lens Ġlaw : Ġget Ġset ") Ġ{ Ġlens Get Set ( lens Gen , Ġa Gen , Ġeq a ) Ġ}, ĊĠĠĠĠĠ ĠLaw (" Lens Ġlaw : Ġset Ġget ") Ġ{ Ġlens Set Get ( lens Gen , Ġa Gen , Ġb Gen , Ġeq b ) Ġ}, ĊĠĠĠĠĠ ĠLaw (" Lens Ġlaw : Ġis Ġset Ġide mpot ent ") Ġ{ Ġlens Set Ide mpot ent ( lens Gen , Ġa Gen , Ġb Gen , Ġeq a ) Ġ}, ĊĠĠĠĠĠ ĠLaw (" Lens Ġlaw : Ġmodify Ġidentity ") Ġ{ Ġlens Modify Identity ( lens Gen , Ġa Gen , Ġeq a ) Ġ}, ĊĠĠĠĠĠ ĠLaw (" Lens Ġlaw : Ġcompose Ġmodify ") Ġ{ Ġlens Compose Modify ( lens Gen , Ġa Gen , Ġfunc Gen , Ġeq a ) Ġ}, ĊĠĠĠĠĠ ĠLaw (" Lens Ġlaw : Ġconsistent Ġset Ġmodify ") Ġ{ Ġlens Cons istent Set Modify ( lens Gen , Ġa Gen , Ġb Gen , Ġeq a ) Ġ} ĊĠĠĠ Ġ) ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠWarning : ĠUse Ġonly Ġwhen Ġa Ġ` Gen . constant ()` Ġapplies ĊĠĠ Ġ*/ ĊĠ Ġfun Ġ< A , ĠB > Ġlaws ( ĊĠĠĠ Ġlens : ĠLens < A , ĠB >, ĊĠĠĠ Ġa Gen : ĠA rb < A >, ĊĠĠĠ Ġb Gen : ĠA rb < B >, ĊĠĠĠ Ġfunc Gen : ĠA rb <( B ) Ġ-> ĠB >, ĊĠĠĠ Ġeq a : Ġ( A , ĠA ) Ġ-> ĠBoolean Ġ= Ġ{ Ġa , Ġb Ġ-> Ġa Ġ== Ġb Ġ}, ĊĠĠĠ Ġeq b : Ġ( B , ĠB ) Ġ-> ĠBoolean Ġ= Ġ{ Ġa , Ġb Ġ-> Ġa Ġ== Ġb Ġ} ĊĠ Ġ): ĠList < Law > Ġ= Ġlaws ( Ar b . constant ( lens ), Ġa Gen , Ġb Gen , Ġfunc Gen , Ġeq a , Ġeq b ) ĊĊĠ Ġsuspend Ġfun Ġ< A , ĠB > Ġlens Get Set ( lens Gen : ĠA rb < Lens < A , ĠB >>, Ġa Gen : ĠA rb < A >, Ġeq : Ġ( A , ĠA ) Ġ-> ĠBoolean ) Ġ= ĊĠĠĠ Ġcheck All ( lens Gen , Ġa Gen ) Ġ{ Ġlens , Ġa Ġ-> ĊĠĠĠĠĠ Ġlens . run Ġ{ ĊĠĠĠĠĠĠĠ Ġset ( a , Ġget ( a )). equal Under The Law ( a , Ġeq ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠ Ġsuspend Ġfun Ġ< A , ĠB > Ġlens Set Get ( lens Gen : ĠA rb < Lens < A , ĠB >>, Ġa Gen : ĠA rb < A >, Ġb Gen : ĠA rb < B >, Ġeq : Ġ( B , ĠB ) Ġ-> ĠBoolean ) Ġ= ĊĠĠĠ Ġcheck All ( lens Gen , Ġa Gen , Ġb Gen ) Ġ{ Ġlens , Ġa , Ġb Ġ-> ĊĠĠĠĠĠ Ġlens . run Ġ{ ĊĠĠĠĠĠĠĠ Ġget ( set ( a , Ġb )). equal Under The Law ( b , Ġeq ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠ Ġsuspend Ġfun Ġ< A , ĠB > Ġlens Set Ide mpot ent ( lens Gen : ĠA rb < Lens < A , ĠB >>, Ġa Gen : ĠA rb < A >, Ġb Gen : ĠA rb < B >, Ġeq : Ġ( A , ĠA ) Ġ-> ĠBoolean ) Ġ= ĊĠĠĠ Ġcheck All ( lens Gen , Ġa Gen , Ġb Gen ) Ġ{ Ġlens , Ġa , Ġb Ġ-> ĊĠĠĠĠĠ Ġlens . run Ġ{ ĊĠĠĠĠĠĠĠ Ġset ( set ( a , Ġb ), Ġb ). equal Under The Law ( set ( a , Ġb ), Ġeq ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠ Ġsuspend Ġfun Ġ< A , ĠB > Ġlens Modify Identity ( lens Gen : ĠA rb < Lens < A , ĠB >>, Ġa Gen : ĠA rb < A >, Ġeq : Ġ( A , ĠA ) Ġ-> ĠBoolean ) Ġ= ĊĠĠĠ Ġcheck All ( lens Gen , Ġa Gen ) Ġ{ Ġlens , Ġa Ġ-> ĊĠĠĠĠĠ Ġlens . run Ġ{ ĊĠĠĠĠĠĠĠ Ġmodify ( a , Ġ:: identity ). equal Under The Law ( a , Ġeq ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠ Ġsuspend Ġfun Ġ< A , ĠB > Ġlens Compose Modify ( lens Gen : ĠA rb < Lens < A , ĠB >>, Ġa Gen : ĠA rb < A >, Ġfunc Gen : ĠA rb <( B ) Ġ-> ĠB >, Ġeq : Ġ( A , ĠA ) Ġ-> ĠBoolean ) Ġ= ĊĠĠĠ Ġcheck All ( lens Gen , Ġa Gen , Ġfunc Gen , Ġfunc Gen ) Ġ{ Ġlens , Ġa , Ġf , Ġg Ġ-> ĊĠĠĠĠĠ Ġlens . run Ġ{ ĊĠĠĠĠĠĠĠ Ġmodify ( modify ( a , Ġf ), Ġg ). equal Under The Law ( modify ( a , Ġg Ġcompose Ġf ), Ġeq ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠ Ġsuspend Ġfun Ġ< A , ĠB > Ġlens Cons istent Set Modify ( lens Gen : ĠA rb < Lens < A , ĠB >>, Ġa Gen : ĠA rb < A >, Ġb Gen : ĠA rb < B >, Ġeq : Ġ( A , ĠA ) Ġ-> ĠBoolean ) Ġ= ĊĠĠĠ Ġcheck All ( lens Gen , Ġa Gen , Ġb Gen ) Ġ{ Ġlens , Ġa , Ġb Ġ-> ĊĠĠĠĠĠ Ġlens . run Ġ{ ĊĠĠĠĠĠĠĠ Ġset ( a , Ġb ). equal Under The Law ( modify ( a ) Ġ{ Ġb Ġ}, Ġeq ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ