package Ġopt ik al . opt ics . l aws Ċ Ċ import Ġio . kot lint est . properties . Gen Ċ import Ġio . kot lint est . properties . for All Ċ import Ġk ategory . Eq Ċ import Ġk ategory . Id Ċ import Ġk ategory . Law Ċ import Ġk ategory . applic ative Ċ import Ġk ategory . compose Ċ import Ġk ategory . identity Ċ import Ġk ategory . value Ċ import Ġopt ik al . opt ics . Optional Ċ Ċ object ĠOptional L aws Ġ{ ĊĊĠĠĠ Ġinline Ġfun Ġ< A , Ġre ified ĠB > Ġlaws ( optional : ĠOptional < A , ĠB >, Ġa Gen : ĠGen < A >, Ġb Gen : ĠGen < B >, Ġfunc Gen : ĠGen <( B ) Ġ-> ĠB >, ĠE QA : ĠEq < A >, ĠE QB : ĠEq < B >): ĠList < Law > Ġ= ĠlistOf ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLaw (" Optional ĠLaw : Ġset Ġwhat Ġyou Ġget ", Ġ{ Ġget Option Set ( optional , Ġa Gen , ĠE QA ) Ġ}), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLaw (" Optional ĠLaw : Ġget Ġwhat Ġyou Ġget ", Ġ{ Ġget Get Option ( optional , Ġa Gen , Ġb Gen , ĠE QB ) Ġ}), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLaw (" Optional ĠLaw : Ġset Ġis Ġide mpot ent ", Ġ{ Ġset Ide mpot ent ( optional , Ġa Gen , Ġb Gen , ĠE QA ) Ġ}), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLaw (" Optional ĠLaw : Ġmodify Ġidentity Ġ= Ġidentity ", Ġ{ Ġmodify Identity ( optional , Ġa Gen , ĠE QA ) Ġ}), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLaw (" Optional ĠLaw : Ġcompose Ġmodify ", Ġ{ Ġcompose Modify ( optional , Ġa Gen , Ġfunc Gen , ĠE QA ) Ġ}), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLaw (" Optional ĠLaw : Ġconsistent Ġset Ġwith Ġmodify ", Ġ{ Ġconsistent Set Modify ( optional , Ġa Gen , Ġb Gen , ĠE QA ) Ġ}), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLaw (" Optional ĠLaw : Ġconsistent Ġmodify Ġwith Ġmodify Ġidentity ", Ġ{ Ġconsistent Modify Modify Id ( optional , Ġa Gen , Ġfunc Gen , ĠE QA ) Ġ}) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ, ĠLaw (" Optional ĠLaw : Ġconsistent Ġget Option Ġwith Ġmodify Ġidentity ", Ġ{ Ġconsistent Get Option Modify Id ( optional , Ġa Gen , ĠE QA ) Ġ}) ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġfun Ġ< A , ĠB > Ġget Option Set ( optional : ĠOptional < A , ĠB >, Ġa Gen : ĠGen < A >, ĠE QA : ĠEq < A >): ĠUnit Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor All ( a Gen , Ġ{ Ġa Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠE QA . eq v ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptional . get Or Modify ( a ). fold (:: identity , Ġ{ Ġoptional . set ( it )( a ) Ġ}), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġa ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠ Ġfun Ġ< A , ĠB > Ġget Get Option ( optional : ĠOptional < A , ĠB >, Ġa Gen : ĠGen < A >, Ġb Gen : ĠGen < B >, ĠE QB : ĠEq < B >): ĠUnit Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor All ( a Gen , Ġb Gen , Ġ{ Ġa , Ġb Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptional . getOption ( optional . set ( b )( a )). exists Ġ{ ĠE QB . eq v ( it , Ġb ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠ Ġfun Ġ< A , ĠB > Ġset Ide mpot ent ( optional : ĠOptional < A , ĠB >, Ġa Gen : ĠGen < A >, Ġb Gen : ĠGen < B >, ĠE QA : ĠEq < A >): ĠUnit Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor All ( a Gen , Ġb Gen , Ġ{ Ġa , Ġb Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠE QA . eq v ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptional . set ( b )( optional . set ( b )( a )), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptional . set ( b )( a ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠ Ġfun Ġ< A , ĠB > Ġmodify Identity ( optional : ĠOptional < A , ĠB >, Ġa Gen : ĠGen < A >, ĠE QA : ĠEq < A >): ĠUnit Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor All ( a Gen , Ġ{ Ġa Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠE QA . eq v ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptional . modify (:: identity )( a ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġa ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĊĊĠĠĠ Ġfun Ġ< A , ĠB > Ġcompose Modify ( optional : ĠOptional < A , ĠB >, Ġa Gen : ĠGen < A >, Ġfunc Gen : ĠGen <( B ) Ġ-> ĠB >, ĠE QA : ĠEq < A >): ĠUnit Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor All ( a Gen , Ġfunc Gen , Ġfunc Gen , Ġ{ Ġa , Ġf , Ġg Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠE QA . eq v ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptional . modify ( g )( optional . modify ( f )( a )), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptional . modify ( g Ġcompose Ġf )( a ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠ Ġfun Ġ< A , ĠB > Ġconsistent Set Modify ( optional : ĠOptional < A , ĠB >, Ġa Gen : ĠGen < A >, Ġb Gen : ĠGen < B >, ĠE QA : ĠEq < A >): ĠUnit Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor All ( a Gen , Ġb Gen , Ġ{ Ġa , b Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠE QA . eq v ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptional . set ( b )( a ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptional . modify Ġ{ Ġb Ġ} ( a ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠ Ġfun Ġ< A , ĠB > Ġconsistent Modify Modify Id ( optional : ĠOptional < A , ĠB >, Ġa Gen : ĠGen < A >, Ġfunc Gen : ĠGen <( B ) Ġ-> ĠB >, ĠE QA : ĠEq < A >): ĠUnit Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor All ( a Gen , func Gen , Ġ{ Ġa , f Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠE QA . eq v ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptional . modify ( f )( a ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptional . modify F ( Id . applic ative (), Ġ{ ĠId . pure ( f ( it )) Ġ}, a Ġ). value () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠ Ġ@ Suppress (" UNUSED _ PARAMETER ") ĊĠĠĠ Ġfun Ġ< A , ĠB > Ġconsistent Get Option Modify Id ( optional : ĠOptional < A , ĠB >, Ġa Gen : ĠGen < A >, ĠE QA : ĠEq < A >): ĠUnit Ġ= ĠTODO (" Figure Ġout Ġsolution Ġto Ġtag Ġtypes ") Ċ Ċ }