coreygirard/elm-zipper/1.0.0

Zipper.ListListList

A special case of Zipper3.SelectList.Zipper where all elements have the same type.

If you're working with Chars, check out Zipper.StringStringString

Definition

type alias Zipper a =
( List a, List a, List a )

A list type that tracks two split locations

= LeftIndex Int
| RightIndex Int
type alias Position =
{ first : Int
, last : Int
, leftSplit : RelativeIndex
, rightSplit : RelativeIndex
, leftEdge : Int
, rightEdge : Int
, section : Section
}
type Section
= Left
| Selected
| Right

Passed to the user-provided function by indexedMap and similar functions to specify the current element's location relative to the selected element

= MoveFirst
| MoveLeft
| MoveNone
| MoveRight
| MoveLast

Create

empty : Zipper a

Create an empty zipper

empty --> ( [], [], [] )
fromTuple : ( List a, List a, List a ) -> Zipper a
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    --> ( [ 3, 2, 1 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
fromZipperListList : List a -> ( List a, List a ) -> Zipper a
( [ 3, 2, 1 ], [ 7, 8, 9 ] )
|> fromZipperListList [4, 5, 6]
    --> fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
fromZipperListElemList : (a -> List a) -> ( List a, a, List a ) -> Zipper a
( [ 3, 2, 1 ], 5, [ 7, 8, 9 ] )
|> fromZipperListElemList (\n -> [4, n, 6])
    --> fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )

To

toTuple : Zipper a -> ( List a, List a, List a )
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> toTuple
    --> ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
toList : Zipper a -> List a
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> toList
    --> [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
toZipperListList : Zipper a -> ( List a, List a )
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> toZipperListList
    --> ( [ 3, 2, 1 ], [ 7, 8, 9 ] )
toZipperListElemList : (List a -> a) -> Zipper a -> ( List a, a, List a )
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> toZipperListElemList List.sum
    --> ( [ 3, 2, 1 ], 15, [ 7, 8, 9 ] )

Length

length : Zipper a -> Int
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> length
    --> 9
positionLeft : Zipper a -> Int
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> positionLeft
    --> 3
positionRight : Zipper a -> Int
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> positionRight
    --> 6

Get

getLeft : Zipper a -> List a
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> getLeft
    --> [ 1, 2, 3 ]
getSelected : Zipper a -> List a
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> getSelected
    --> [ 4, 5, 6 ]
getRight : Zipper a -> List a
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> getRight
    --> [ 7, 8, 9 ]

Set

setLeft : List a -> Zipper a -> Zipper a
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> setLeft [ 11, 12, 13 ]
    --> fromTuple ( [ 11, 12, 13 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
setSelected : List a -> Zipper a -> Zipper a
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> setSelected [ 14, 15, 16 ]
    --> fromTuple ( [ 1, 2, 3 ], [ 14, 15, 16 ], [ 7, 8, 9 ] )
setRight : List a -> Zipper a -> Zipper a
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> setRight [ 17, 18, 19 ]
    --> fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 17, 18, 19 ] )

Map

map : (a -> b) -> Zipper a -> Zipper b
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> map ((+) 10)
    --> fromTuple ( [ 11, 12, 13 ], [ 14, 15, 16 ], [ 17, 18, 19 ] )
indexedMap : (Position -> a -> b) -> Zipper a -> Zipper b
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> indexedMap (\{ first, leftEdge } val -> first * 100 + leftEdge * 10 + val)
    --> fromTuple ( [ 1, 112, 223 ], [ 304, 415, 526 ], [ 607, 718, 829 ] )

Update

update : (List a -> List b) -> Zipper a -> Zipper b
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> update (\elems -> 0 :: elems)
    --> fromTuple ( [ 0, 1, 2, 3 ], [ 0, 4, 5, 6 ], [ 0, 7, 8, 9 ] )
updateLeft : (List a -> List a) -> Zipper a -> Zipper a
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> updateLeft (\elems -> 0 :: elems)
    --> fromTuple ( [ 0, 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
updateSelected : (List a -> List a) -> Zipper a -> Zipper a
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> updateSelected (\elems -> 0 :: elems)
    --> fromTuple ( [ 1, 2, 3 ], [ 0, 4, 5, 6 ], [ 7, 8, 9 ] )
updateRight : (List a -> List a) -> Zipper a -> Zipper a
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> updateRight (\elems -> 0 :: elems)
    --> fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 0, 7, 8, 9 ] )

Filter

filter : (a -> Bool) -> Zipper a -> Zipper a
fromTuple ( [ 1, 2, 3, 4 ], [ 5, 6, 7, 8 ], [ 9, 10, 11, 12 ] )
    |> filter (modBy 2 >> (==) 0)
    --> fromTuple ( [ 2, 4 ], [ 6, 8 ], [ 10, 12 ] )
indexedFilter : (Position -> a -> Bool) -> Zipper a -> Zipper a
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> indexedFilter (\{ section, rightEdge } val -> section == Left || rightEdge == 0 || val == 7)
    --> fromTuple ( [ 1, 2, 3 ], [ 6 ], [ 7, 9 ] )


fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> indexedFilter (\{ leftEdge, rightEdge } val -> leftEdge == 0 || rightEdge == 0)
    --> fromTuple ( [ 1, 3 ], [ 4, 6 ], [ 7, 9 ] )

Move

move : MoveDirection -> MoveDirection -> Zipper a -> Maybe (Zipper a)
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> move MoveLeft MoveLast
    --> Just (fromTuple ( [ 1, 2 ], [ 3, 4, 5, 6, 7, 8, 9 ], [] ))
tryMove : MoveDirection -> MoveDirection -> Zipper a -> Zipper a

Insert

insertFirst : a -> Zipper a -> Zipper a
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> insertFirst 0
    --> fromTuple ( [ 0, 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
insertLast : a -> Zipper a -> Zipper a
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> insertLast 0
    --> fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9, 0 ] )
insertLeftOfLeftSplit : a -> Zipper a -> Zipper a
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> insertLeftOfLeftSplit 0
    --> fromTuple ( [ 1, 2, 3, 0 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
insertRightOfLeftSplit : a -> Zipper a -> Zipper a
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> insertRightOfLeftSplit 0
    --> fromTuple ( [ 1, 2, 3 ], [ 0, 4, 5, 6 ], [ 7, 8, 9 ] )
insertLeftOfRightSplit : a -> Zipper a -> Zipper a
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> insertLeftOfRightSplit 0
    --> fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6, 0 ], [ 7, 8, 9 ] )
insertRightOfRightSplit : a -> Zipper a -> Zipper a
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> insertRightOfRightSplit 0
    --> fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 0, 7, 8, 9 ] )

Reverse

reverse : Zipper a -> Zipper a
fromTuple ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] )
    |> reverse
    --> fromTuple ( [ 9, 8, 7 ], [ 6, 5, 4 ], [ 3, 2, 1 ] )

Swap

Sort

sortKeepIndexes : Zipper comparable -> Zipper comparable

Indexes

Zipper a
-> { left : List Position
, selected : List Position
, right : List Position
}
calcIndex : Zipper a -> Int -> Maybe Position
calcIndexLeft : Lengths -> Int -> Position
calcIndexSelected : Lengths -> Int -> Position
calcIndexRight : Lengths -> Int -> Position
zipper : Zipper Int
zipper = ( [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 0 ] )


indexRelativeLeftToAbsolute zipper (LeftIndex 2) --> 0


indexRelativeLeftToAbsolute zipper (LeftIndex 0) --> 2


indexRelativeLeftToAbsolute zipper (RightIndex 0) --> 3


indexRelativeLeftToAbsolute zipper (RightIndex 2) --> 5


indexRelativeLeftToAbsolute zipper (RightIndex 3) --> 6


indexRelativeLeftToAbsolute zipper (RightIndex 5) --> 8
zipper : Zipper Int
zipper = ( [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 0 ] )


indexRelativeRightToAbsolute zipper (LeftIndex 5) --> 0


indexRelativeRightToAbsolute zipper (LeftIndex 3) --> 2


indexRelativeRightToAbsolute zipper (LeftIndex 2) --> 3


indexRelativeRightToAbsolute zipper (LeftIndex 0) --> 5


indexRelativeRightToAbsolute zipper (RightIndex 0) --> 6


indexRelativeRightToAbsolute zipper (RightIndex 2) --> 8