strengthening the zipper - imperial college londontora/clase/clase-ldta09-slides.pdf ·...

36
Allwood & Eisenbach Strengthening the Zipper Strengthening the Zipper CLASE - Cursor Library for A Structured Editor Tristan Allwood ([email protected]) Susan Eisenbach ([email protected]) Zip! Photo from http://www.flickr.com/photos/sarmax/109561164/

Upload: others

Post on 12-Jun-2020

10 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

Strengthening the Zipper

CLASE - Cursor Library for A Structured Editor

Tristan Allwood ([email protected])Susan Eisenbach ([email protected])

Zip! Photo from http://www.flickr.com/photos/sarmax/109561164/

Page 2: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

Motivation

Page 3: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

Motivation

● In place updates● Side effects● Pointers● IO

Page 4: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

Motivation

● In place updates● Side effects● Pointers● IO

Page 5: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

Towards Clase Zippers

data Root = Root Stat

data Stat  = Assign Var IExp  | If BExp Stat  | Stat `Then` Stat

data IExp  = Add IExp IExp  | IVar Var  | Const Int

data BExp  = LT IExp IExp  | GT IExp IExp

Page 6: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

Towards CLASE ZippersRoot

Then

Assign “x” If

Const 3 LT

IVar “x” Const 4

Assign “y”

Const 4

data Root = Root Stat

data Stat  = Assign Var IExp  | If BExp Stat  | Stat `Then` Stat

data IExp  = Add IExp IExp  | IVar Var  | Const Int

data BExp  = LT IExp IExp  | GT IExp IExp

Cursor {  it = Root ((Assign “x” (Const 3) `Then`              (If (LT (IVar “x”) (Const 4)) (Assign “y” (Const 4))),  ctx = Stop}  :: Cursor Root

data Cursor a = Cursor {   it :: a,  ctx :: Path ContextI a Root}

data Path tc start end where  Stop :: Path here here  Step :: tc start mid →          Path tc mid end   →          Path tc start end

it ctx

Stop

Page 7: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

Towards CLASE ZippersRoot

Then

Assign “x” If

Const 3 LT

IVar “x” Const 4

Assign “y”

Const 4

data Root = Root Stat

data Stat  = Assign Var IExp  | If BExp Stat  | Stat `Then` Stat

data IExp  = Add IExp IExp  | IVar Var  | Const Int

data BExp  = LT IExp IExp  | GT IExp IExp

Cursor {  it = Root ((Assign “x” (Const 3) `Then`              (If (LT (IVar “x”) (Const 4)) (Assign “y” (Const 4))),  ctx = Stop}  :: Cursor Root

data Cursor a = Cursor {   it :: a,  ctx :: Path ContextI a Root}

data Path tc start end where  Stop :: Path here here  Step :: tc start mid →          Path tc mid end   →          Path tc start end

it ctx

Stop

Page 8: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

Towards CLASE ZippersRoot'

Then

Assign “x” If

Const 3 LT

IVar “x” Const 4

Assign “y”

Const 4

data Root = Root Stat

data Stat  = Assign Var IExp  | If BExp Stat  | Stat `Then` Stat

data IExp  = Add IExp IExp  | IVar Var  | Const Int

data BExp  = LT IExp IExp  | GT IExp IExp

Cursor {  it = ((Assign “x” (Const 3) `Then`              (If (LT (IVar “x”) (Const 4)) (Assign “y” (Const 4))),  ctx = Step Root' Stop}  :: Cursor Stat

data Cursor a = Cursor {   it :: a,  ctx :: Path ContextI a Root}

data Path tc start end where  Stop :: Path here here  Step :: tc start mid →          Path tc mid end   →          Path tc start end

it ctx

Stop

Root' :: ContextI Stat Root

Page 9: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

Towards CLASE ZippersRoot'

Then

Assign “x” If

Const 3 LT

IVar “x” Const 4

Assign “y”

Const 4

data Root = Root Stat

data Stat  = Assign Var IExp  | If BExp Stat  | Stat `Then` Stat

data IExp  = Add IExp IExp  | IVar Var  | Const Int

data BExp  = LT IExp IExp  | GT IExp IExp

Cursor {  it = ((Assign “x” (Const 3) `Then`              (If (LT (IVar “x”) (Const 4)) (Assign “y” (Const 4))),  ctx = Step Root' Stop}  :: Cursor Stat

data Cursor a = Cursor {   it :: a,  ctx :: Path ContextI a Root}

data Path tc start end where  Stop :: Path here here  Step :: tc start mid →          Path tc mid end   →          Path tc start end

it ctx

Stop

Root' :: ContextI Stat Root

Page 10: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

Towards CLASE Zippers

Root'

Then'1

If

LT

IVar “x” Const 4

Assign “y”

Const 4

data Root = Root Stat

data Stat  = Assign Var IExp  | If BExp Stat  | Stat `Then` Stat

data IExp  = Add IExp IExp  | IVar Var  | Const Int

data BExp  = LT IExp IExp  | GT IExp IExp

Cursor {  it =  If (LT (IVar “x”) (Const 4)) (Assign “y” (Const 4)),    ctx = Step (Then'1 (Assign “x” (Const 3))) (Step Root' Stop)}  :: Cursor Stat

data Cursor a = Cursor {   it :: a,  ctx :: Path ContextI a Root}

data Path tc start end where  Stop :: Path here here  Step :: tc start mid →          Path tc mid end   →          Path tc start end

it ctx

Stop

Root' :: ContextI Stat Root

Then'1 :: ContextI Stat Stat

Assign “x”

Const 3

Page 11: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

Towards CLASE Zippers

Root'

Then'1

If

LT

IVar “x” Const 4

Assign “y”

Const 4

data Root = Root Stat

data Stat  = Assign Var IExp  | If BExp Stat  | Stat `Then` Stat

data IExp  = Add IExp IExp  | IVar Var  | Const Int

data BExp  = LT IExp IExp  | GT IExp IExp

Cursor {  it =  If (LT (IVar “x”) (Const 4)) (Assign “y” (Const 4)),    ctx = Step (Then'1 (Assign “x” (Const 3))) (Step Root' Stop)}  :: Cursor Stat

data Cursor a = Cursor {   it :: a,  ctx :: Path ContextI a Root}

data Path tc start end where  Stop :: Path here here  Step :: tc start mid →          Path tc mid end   →          Path tc start end

it ctx

Stop

Root' :: ContextI Stat Root

Then'1 :: ContextI Stat Stat

Assign “x”

Const 3

Page 12: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

Towards CLASE Zippers

Root'

Then'1

If'BExp

LT

IVar “x” Const 4

data Root = Root Stat

data Stat  = Assign Var IExp  | If BExp Stat  | Stat `Then` Stat

data IExp  = Add IExp IExp  | IVar Var  | Const Int

data BExp  = LT IExp IExp  | GT IExp IExp

Cursor {  it =  LT (IVar “x”) (Const 4),   ctx = Step (If'BExp (Assign “y” (Const 4))) (Step (Then'1 (Assign “x” (Const 3))) (Step Root' Stop))}  :: Cursor BExp

data Cursor a = Cursor {   it :: a,  ctx :: Path ContextI a Root}

data Path tc start end where  Stop :: Path here here  Step :: tc start mid →          Path tc mid end   →          Path tc start end

it ctx

Stop

Root' :: ContextI Stat Root

Then'1 :: ContextI Stat Stat

If'BExp :: ContextI BExp Stat

Assign “x”

Const 3

Assign “y”

Const 4

Page 13: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

Bookmarks

Page 14: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

BookmarksRoot

Then

Assign “x” If

Const 3 LT

IVar “x” Const 4

Assign “y”

Const 4

data Path tc start end where  Stop :: Path here here  Step :: tc start mid →          Path tc mid end   →          Path tc start end

data Route from to where  Route ::  Path (MovementI Up) from mid   →            Path (MovementI Down) mid to   →            Route from to 

Page 15: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

BookmarksRoot

Then

Assign “x” If

Const 3

IVar “x” Const 4

Assign “y”

Const 4

data Path tc start end where  Stop :: Path here here  Step :: tc start mid →          Path tc mid end   →          Path tc start end

data Route from to where  Route ::  Path (MovementI Up) from mid   →            Path (MovementI Down) mid to   →            Route from to 

LT

Page 16: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

BookmarksRoot

Then

Assign “x” If

Const 3

IVar “x” Const 4

Assign “y”

Const 4

Route (Step (MUp MAssignToIExp) Stop)       (Stop) :: Route IExp Exp 

data Path tc start end where  Stop :: Path here here  Step :: tc start mid →          Path tc mid end   →          Path tc start end

data Route from to where  Route ::  Path (MovementI Up) from mid   →            Path (MovementI Down) mid to   →            Route from to 

LT

MUp :: MovementI Down b a   MovementI Up a b→

MAssignToIExp :: MovementI Down Exp IExp

Page 17: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

BookmarksRoot

Then

Assign “x” If

Const 3

IVar “x” Const 4

Assign “y”

Const 4

Route (Step (MUp MAssignToIExp) (Step (MUp MThenToExp1) Stop))      (Stop) :: Route IExp Exp 

data Path tc start end where  Stop :: Path here here  Step :: tc start mid →          Path tc mid end   →          Path tc start end

data Route from to where  Route ::  Path (MovementI Up) from mid   →            Path (MovementI Down) mid to   →            Route from to 

LT

MUp :: MovementI Down b a   MovementI Up a b→

MAssignToIExp :: MovementI Down Exp IExp

MThenToIExp1 :: MovementI Down Exp Exp

Page 18: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

BookmarksRoot

Then

Assign “x” If

Const 3

IVar “x” Const 4

Assign “y”

Const 4

Route (Step (MUp MAssignToIExp) (Step (MUp MThenToExp1) Stop))      (Step MThenToIExp2 Stop) :: Route IExp Exp 

data Path tc start end where  Stop :: Path here here  Step :: tc start mid →          Path tc mid end   →          Path tc start end

data Route from to where  Route ::  Path (MovementI Up) from mid   →            Path (MovementI Down) mid to   →            Route from to 

LT

MUp :: MovementI Down b a   MovementI Up a b→

MAssignToIExp :: MovementI Down Exp IExp

MThenToIExp1 :: MovementI Down Exp Exp

MThenToIExp2 :: MovementI Down Exp Exp

Page 19: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

BookmarksRoot

Then

Assign “x” If

Const 3

IVar “x” Const 4

Assign “y”

Const 4

Route (Step (MUp MAssignToIExp) (Step (MUp MThenToExp1) Stop))      (Step MThenToIExp2 (Step MIfToBExp Stop)) :: Route IExp BExp 

data Path tc start end where  Stop :: Path here here  Step :: tc start mid →          Path tc mid end   →          Path tc start end

data Route from to where  Route ::  Path (MovementI Up) from mid   →            Path (MovementI Down) mid to   →            Route from to 

LT

MUp :: MovementI Down b a   MovementI Up a b→

MAssignToIExp :: MovementI Down Exp IExp

MThenToIExp1 :: MovementI Down Exp Exp

MThenToIExp2 :: MovementI Down Exp Exp

MIfToBExp :: MovementI Down Exp BExp

Page 20: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

Cursors with Bookmarks

Root'

Then'1

If

LT

IVar “x” Const 4

Assig “y”

Const 4

Cursor {  it =  If (LT (IVar “x”) (Const 4)) (Assig “y” (Const 4)),   ctx = Step (Then'1 (Assig “x” (Const 3))) (Step Root' Stop)

}  :: Cursor Stat

data Cursor a = Cursor {   it :: a,  ctx :: Path ContextI a Root}

it ctx

Stop

Assig “x”

Const 3

Page 21: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

Cursors with Bookmarks

Root'

Then'1

If

LT

IVar “x” Const 4

Assig “y”

Const 4

Cursor {  it =  If (LT (IVar “x”) (Const 4)) (Assig “y” (Const 4)),    ctx = Step (Then'1 (Assig “x” (Const 3))) (Step Root' Stop),  log = Route Stop (Step MIfToExp (Step MAssigToIExp Stop))}  :: Cursor IExp Stat

data Cursor x a = Cursor {   it :: a,  ctx :: Path ContextI a Root,  log :: Route a x}

it ctx

Stop

Assig “x”

Const 3

Page 22: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

Movingdata Cursor x a = Cursor {     it :: a,    ctx :: Path ContextI a Root,    log :: Route a x  }

genericMoveUp, genericMoveDown, genericMoveLeft, genericMoveRight 

:: Cursor x a   Maybe ( a' . Cursor x a')→ ∃

Page 23: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

Writing a GUI

data CursorHolder where  CH :: Cursor a a   →        Map Int ( a' . Route a a')   ∃ →

CursorHolder

mainLoop cursorHolder = dokey   getKey←let cursorHolder' = onKeyPress key cursorHolderrender cursorHolder'mainLoop cursorHolder'

Page 24: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

onKeyPress – new bookmark

onKeyPress (KeySaveBookmark i) (CH cursor bookmarks)=  let bookmarks' = Map.insert i (Exists emptyRoute) 

 bookmarksin  CH cursor bookmarks'

data CursorHolder where  CH :: Cursor a a   →        Map Int ( a' . Route a a') →∃        CursorHolder

emptyRoute :: Route a aemptyRoute = Route Stop Stop

Page 25: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

onKeyPress - movementdata CursorHolder where  CH :: Cursor Lam a a   →        Map Int ( a' . Route a a') ∃ →        CursorHolder

data CursorHolder where  CH :: Cursor a a   →        Map Int ( a' . Route a a') ∃ →        CursorHolder

onKeyPress KeyDown ch@(CH cursor bookmarks) = fromMaybe ch $ do  Exists cursor'   genericMoveDown cursor←  ...

Page 26: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

onKeyPress - movementdata CursorHolder where  CH :: Cursor Lam a a   →        Map Int ( a' . Route a a') ∃ →        CursorHolder

data CursorHolder where  CH :: Cursor a a   →        Map Int ( a' . Route a a') ∃ →        CursorHolder

onKeyPress KeyDown ch@(CH cursor bookmarks) = fromMaybe ch $ do  Exists cursor'   genericMoveDown cursor←  ...

 ∃ o .

 ∃ n .

cursor :: Cursor o o

cursor' :: Cursor o n

bookmarks :: Map Int ( a' . Route o a')∃

Page 27: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

onKeyPress - movementdata CursorHolder where  CH :: Cursor Lam a a   →        Map Int ( a' . Route a a') ∃ →        CursorHolder

data CursorHolder where  CH :: Cursor a a   →        Map Int ( a' . Route a a') ∃ →        CursorHolder

onKeyPress KeyDown ch@(CH cursor bookmarks) = fromMaybe ch $ do  Exists cursor'   genericMoveDown cursor←  return (CH cursor' bookmarks)

 ∃ o .

 ∃ n .

cursor :: Cursor o o

cursor' :: Cursor o n

bookmarks :: Map Int ( a' . Route o a')∃

Page 28: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

onKeyPress - movementdata CursorHolder where  CH :: Cursor Lam a a   →        Map Int ( a' . Route a a') ∃ →        CursorHolder

data CursorHolder where  CH :: Cursor a a   →        Map Int ( a' . Route a a') ∃ →        CursorHolder

onKeyPress KeyDown ch@(CH cursor bookmarks) = fromMaybe ch $ do  Exists cursor'   genericMoveDown cursor←  let bookmarks' =    Map.map (\∃ bm   → ∃ (log cursor' `appendRoute` bm))            bookmarks

 ∃ o .

 ∃ n .

cursor :: Cursor o o

cursor' :: Cursor o n

bookmarks :: Map Int ( a'.Route o a')∃

appendRoute :: Route a b   →  Route b c   →

               Route a c

bookmarks' :: Map Int ( a'.Route n a')∃

Page 29: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

onKeyPress - movementdata CursorHolder where  CH :: Cursor Lam a a   →        Map Int ( a' . Route a a') ∃ →        CursorHolder

data CursorHolder where  CH :: Cursor a a   →        Map Int ( a' . Route a a') ∃ →        CursorHolder

onKeyPress KeyDown ch@(CH cursor bookmarks) = fromMaybe ch $ do  Exists cursor'   genericMoveDown cursor←  let bookmarks' =    Map.map (\∃ bm   → ∃ (log cursor' `appendRoute` bm))            bookmarks  return (CH cursor' bookmarks')

 ∃ o .

 ∃ n .

cursor :: Cursor o o

cursor' :: Cursor o n

bookmarks :: Map Int ( a'.Route o a')∃

appendRoute :: Route a b   →  Route b c   →

               Route a c

bookmarks' :: Map Int ( a'.Route n a')∃

Page 30: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

onKeyPress - movementdata CursorHolder where  CH :: Cursor Lam a a   →        Map Int ( a' . Route a a') ∃ →        CursorHolder

data CursorHolder where  CH :: Cursor a a   →        Map Int ( a' . Route a a') ∃ →        CursorHolder

onKeyPress KeyDown ch@(CH cursor bookmarks) = fromMaybe ch $ do  Exists cursor'   genericMoveDown cursor←  let bookmarks' =    Map.map (\∃ bm   → ∃ (log cursor' `appendRoute` bm))            bookmarks  return (CH (resetLog cursor') bookmarks')

 ∃ o .

 ∃ n .

cursor :: Cursor o o

cursor' :: Cursor o n

bookmarks :: Map Int ( a'.Route o a')∃

resetLog :: Cursor x a   →            Cursor a a

bookmarks' :: Map Int ( a'.Route n a')∃

Page 31: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

onKeyPress - movementdata CursorHolder where  CH :: Cursor Lam a a   →        Map Int ( a' . Route a a') ∃ →        CursorHolder

data CursorHolder where  CH :: Cursor a a   →        Map Int ( a' . Route a a') ∃ →        CursorHolder

onKeyPress KeyDown ch@(CH cursor bookmarks) = fromMaybe ch $ do  Exists cursor'   genericMoveDown cursor←  let bookmarks' =    Map.map (\∃ bm   → ∃ (log cursor' `appendRoute` bm))            bookmarks  return (CH (resetLog cursor') bookmarks')

 ∃ o .

 ∃ n .

cursor :: Cursor o o

cursor' :: Cursor o n

bookmarks :: Map Int ( a'.Route o a')∃

resetLog :: Cursor x a   →            Cursor a a

bookmarks' :: Map Int ( a'.Route n a')∃

So the Cursor design means the invariant:

Bookmarks stay in sync with focus

Can be partially encoded in the type system

and checked statically by the compiler

Page 32: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

onKeyPress - movementdata CursorHolder where  CH :: Cursor Lam a a   →        Map Int ( a' . Route a a') ∃ →        CursorHolder

data CursorHolder where  CH :: Cursor a a   →        Map Int ( a' . Route a a') ∃ →        CursorHolder

onKeyPress KeyDown ch@(CH cursor bookmarks) = fromMaybe ch $ do  Exists cursor'   genericMoveDown cursor←  let bookmarks' =    Map.map (\∃ bm   → ∃ (log cursor' `appendRoute` bm))            bookmarks  return (CH (resetLog cursor') bookmarks')

 ∃ o .

 ∃ n .

cursor :: Cursor o o

cursor' :: Cursor o n

bookmarks :: Map Int ( a'.Route o a')∃

resetLog :: Cursor x a   →            Cursor a a

bookmarks' :: Map Int ( a'.Route n a')∃

So the Cursor design means the invariant:

Bookmarks stay in sync with focus

Can be partially encoded in the type system

and checked statically by the compiler

Page 33: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

onKeyPress - movementdata CursorHolder where  CH :: Cursor Lam a a   →        Map Int ( a' . Route a a') ∃ →        CursorHolder

data CursorHolder where  CH :: Cursor a a   →        Map Int ( a' . Route a a') ∃ →        CursorHolder

onKeyPress KeyDown ch@(CH cursor bookmarks) = fromMaybe ch $ do  Exists cursor'   genericMoveDown cursor←  let bookmarks' =    Map.map (\∃ bm   → ∃ (log cursor' `appendRoute` bm))            bookmarks  return (CH (resetLog cursor') bookmarks')

 ∃ o .

 ∃ n .

cursor :: Cursor o o

cursor' :: Cursor o n

bookmarks :: Map Int ( a'.Route o a')∃

resetLog :: Cursor x a   →            Cursor a a

bookmarks' :: Map Int ( a'.Route n a')∃

So the Cursor design means the invariant:

Bookmarks stay in sync with focus

Can be partially encoded in the type system

and checked statically by the compiler

Page 34: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

onKeyPress - select bookmark

onKeyPress (KeyLoadBookmark i) ch@(CH cursor bookmarks) = fromMaybe ch $ do  Exists route   Map.lookup i bookmarks←  Exists cursor'   cursor `followRoute` route←  let bookmarks' =    Map.map (\∃ bm   → ∃ (log cursor' `appendRoute` bm))            bookmarks  return (CH (resetLog cursor') bookmarks')

followRoute :: Cursor x a   Route a c   Maybe (Cursor x c)→ →

Page 35: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

CLASE also supports...

● Automatic generation of Context and primitive Movement data types from simple data type declarations

● Automatic generation of a closed reflection scheme for user data types

● Adapters to help with traversals of a Cursor, suitable for (e.g) rendering a Cursor

● Interface to add bound information to traversals

● Simple Persistence (Read/Show) for Cursors

Page 36: Strengthening the Zipper - Imperial College Londontora/clase/CLASE-LDTA09-Slides.pdf · Strengthening the Zipper Allwood & Eisenbach Strengthening the Zipper CLASE - Cursor Library

Allwood & EisenbachStrengthening the Zipper

Thank you for listening!

www.zonetora.co.uk/clase/