1 import Base 2 import bundle_pack.bend as B 3 import world.bend as W 4 5 type Restore is Type: 6 Restored{world:World,payload:P} 7 Pending{world:World,recovery:Q,error:W.WorldError} 8 type Attempt is Type: 9 Installed{world:World,undo:World -> Restore} 10 Refused{world:World,payload:P,error:W.WorldError} 11 Quarantined{world:World,recovery:Q,error:W.WorldError} 12 type Recovery is Type: 13 HeadPending{head:HQ,tail:Tail} 14 TailPending{undoHead:World -> Restore,tail:TQ} 15 def restored_head(~World:Type,~H:Type,~HQ:Type,~Tail:Type,~TQ:Type,result:Restore,tail:Tail) -> Restore,Recovery>: 16 match result: 17 case Restored{world,head}: Restored{world,B.Pack{head,tail}} 18 case Pending{world,head,error}: Pending{world,HeadPending{head,tail},error} 19 def restored_tail(~World:Type,~H:Type,~HQ:Type,~Tail:Type,~TQ:Type,undoHead:World -> Restore,result:Restore) -> Restore,Recovery>: 20 match result: 21 case Restored{world,tail}: restored_head(~World,~H,~HQ,~Tail,~TQ,undoHead(world),tail) 22 case Pending{world,tail,error}: Pending{world,TailPending{undoHead,tail},error} 23 def refused_head(~World:Type,~H:Type,~HQ:Type,~Tail:Type,~TQ:Type,result:Restore,tail:Tail,error:W.WorldError) -> Attempt,Recovery>: 24 match result: 25 case Restored{world,head}: Refused{world,B.Pack{head,tail},error} 26 case Pending{world,head,restoreError}: Quarantined{world,HeadPending{head,tail},restoreError} 27 def installed_tail(~World:Type,~H:Type,~HQ:Type,~Tail:Type,~TQ:Type,undoHead:World -> Restore,result:Attempt) -> Attempt,Recovery>: 28 match result: 29 case Refused{world,tail,error}: refused_head(~World,~H,~HQ,~Tail,~TQ,undoHead(world),tail,error) 30 case Quarantined{world,tail,error}: Quarantined{world,TailPending{undoHead,tail},error} 31 case Installed{world,undoTail}: Installed{world,w => restored_tail(~World,~H,~HQ,~Tail,~TQ,undoHead,undoTail(w))} 32 def installed_head(~World:Type,~H:Type,~HQ:Type,~Tail:Type,~TQ:Type,~installTail:World -> Tail -> Attempt,result:Attempt,tail:Tail) -> Attempt,Recovery>: 33 match result: 34 case Refused{world,head,error}: Refused{world,B.Pack{head,tail},error} 35 case Quarantined{world,head,error}: Quarantined{world,HeadPending{head,tail},error} 36 case Installed{world,undo}: installed_tail(~World,~H,~HQ,~Tail,~TQ,undo,installTail(world,tail)) 37 def install(~World:Type,~H:Type,~HQ:Type,~Tail:Type,~TQ:Type,~installHead:World -> H -> Attempt,~installTail:World -> Tail -> Attempt,world:World,payload:B.Pack) -> Attempt,Recovery>: 38 match payload: 39 case B.Pack{head,tail}: installed_head(~World,~H,~HQ,~Tail,~TQ,~installTail,installHead(world,head),tail) 40 def terminal(~World:Type,world:World,payload:Unit) -> Attempt: 41 Installed{world,w => Restored{w,Unit{}}}