ekmett / zippers

Zippers based on lenses and traversals
Other
38 stars 14 forks source link

Fix Issue #10 #12

Closed anka-213 closed 8 years ago

anka-213 commented 8 years ago

The old code said "If the left branch is empty, then ignore the right branch", which is obviously wrong. The intended behavior was to replace the empty branch with a "Pure".

Test case:

import Control.Zipper
import Control.Lens

-- A tree with potentially empty branches
data T a = Lf a | Nil | Node (T a) (T a) deriving Show

-- A traversal for the tree
trav :: Traversal (T a) (T b) a b
trav k = go where
 go Nil        = pure Nil
 go (Lf a)     = Lf <$> k a
 go (Node a b) = Node <$> go a <*> go b

-- This tree triggers the bug.
brokenTree :: T Int
brokenTree = (Lf 1`Node`Nil) `Node` Lf 2

main =   zipper brokenTree
     &   within trav -- A zipper pointing at "Lf 1"
     >>= rightward   -- At this point, the "Lf 1" is forgotten
     <&> rezip       -- This line fails with "jacketOuts: wrong shape"
     >>= print

This is (most likely) the cause of bug #10.

anka-213 commented 8 years ago

An alternative, way shorter test case:

zipper [Just 1, Nothing, Just 2] & fromWithin (traverse._Just) & rightmost & tug leftward & rezip