This package provides an implementation of a List Zipper as well as its corresponding comonadic interface, namely, the functions extract
, duplicate
and extend
.
These are useful to perform transformations which depend on the neighborhood of the elements, see extend
for one such example.
You can find more complete examples here.
A Zipper a
is a nonempty list with a focused element.
append : List a -> Zipper a -> Zipper a
Add elements at the end of the Zipper.
import Zipper exposing (Zipper(..))
Zipper.append [ 5, 4 ] (Zipper [ 0 ] 1 [ 2, 3 ]) == Zipper [ 0 ] 1 [ 2, 3, 5, 4 ]
prepend : List a -> Zipper a -> Zipper a
Add elements at the beginning of the Zipper.
import Zipper exposing (Zipper(..))
Zipper.prepend [ -1, -2 ] (Zipper [ 0 ] 1 [ 2, 3 ]) == Zipper [ -1, -2, 0 ] 1 [ 2, 3 ]
toList : Zipper a -> List a
Transforms a Zipper into a regular list.
import Zipper exposing (Zipper(..))
Zipper.toList (Zipper [0] 1 [2,3,4]) == [0,1,2,3,4]
prev : Zipper a -> List a
Returns the elements before the focused element.
import Zipper exposing (Zipper(..))
Zipper.prev (Zipper [0] 1 [2,3,4]) == [0]
extract : Zipper a -> a
Returns the focused element.
import Zipper exposing (Zipper(..))
Zipper.extract (Zipper [0] 1 [2,3,4]) == 1
next : Zipper a -> List a
Returns the elements after the focused element.
import Zipper exposing (Zipper(..))
Zipper.next (Zipper [0] 1 [2,3,4]) == [2,3,4]
leftMay : Zipper a -> Maybe (Zipper a)
Attempts to select the element to the left of the focus, returns Nothing
if there are no previous elements.
import Zipper exposing (Zipper(..))
Zipper.leftMay (Zipper [] 1 [2,3,4]) == Nothing
Zipper.leftMay (Zipper [1] 2 [3,4]) == Just (Zipper [] 1 [2, 3, 4])
rightMay : Zipper a -> Maybe (Zipper a)
Attempts to select the element to the right of the focus, returns Nothing
if there are no next elements.
import Zipper exposing (Zipper(..))
Zipper.rightMay (Zipper [0] 1 []) == Nothing
Zipper.rightMay (Zipper [1] 2 [3,4]) == Just (Zipper [1, 2] 3 [4])
left : Zipper a -> Zipper a
Attempts to select the element to the left of the focus. Returns the Zipper unchanged if there are no previous elements.
import Zipper exposing (Zipper(..))
Zipper.left (Zipper [] 1 [2,3,4]) == Zipper [] 1 [2,3,4]
Zipper.left (Zipper [1] 2 [3,4]) == Zipper [] 1 [2, 3, 4]
right : Zipper a -> Zipper a
Attempts to select the element to the right of the focus. Returns the Zipper unchanged if there are no next elements.
import Zipper exposing (Zipper(..))
Zipper.right (Zipper [0] 1 []) == Zipper [0] 1 []
Zipper.right (Zipper [1] 2 [3,4]) == Zipper [1, 2] 3 [4]
map : (a -> b) -> Zipper a -> Zipper b
Apply a function to every element in the Zipper.
import Zipper exposing (Zipper(..))
Zipper.map (\x -> 2 * x) (Zipper [2, 0, 5] 1 [2]) == Zipper [4, 0, 10] 2 [4]
duplicate : Zipper a -> Zipper (Zipper a)
Returns a Zipper in which every element is a Zipper list.
import Zipper exposing (Zipper(..))
duplicate (Zipper [0] 1 [2]) == Zipper [Zipper [] 0 [1,2]] (Zipper [0] 1 [2]) [Zipper [0, 1] 2 []]
extend : (Zipper a -> b) -> Zipper a -> Zipper b
Map elements in the Zipper, having access to the elements before and after it.
import Zipper exposing (Zipper(..))
maxSoFar (Zipper prev curr _) = List.foldr Basics.max curr prev
Zipper.extend maxSoFar (Zipper [2, 1, 3, 4, 5] 1 [2]) == Zipper [2, 2, 3, 4, 5] 5 [5]