This is an alternative site for discovering Elm packages. You may be looking for the official Elm package site instead.
1.0.0 1.0.1
README

ZipList

A ZipList is a collection which can be moved forward/backward and that exposes a single current element

ZipLists

type ZipList a = Empty | Zipper (List a) a (List a)

A collection data type that can be moved forward/backward and that exposes a current element (see the current function)

Creation

fromList : List a -> ZipList a

Craft a new ZipList out of a List

singleton : a -> ZipList a

Create a new ZipList with a single element in it

Consultation

current : ZipList a -> Maybe a

Return the current element of a ZipList. Nothing will be returned if the ziplist is empty

toList : ZipList a -> List a

Convert a ZipList into a List

length : ZipList a -> Int

Return a ZipList length

Moving

forward : ZipList a -> ZipList a

Move forward a ZipList

backward : ZipList a -> ZipList a

Move backward a ZipList

module ZipList
    exposing
        ( ZipList
        , fromList
        , singleton
        , current
        , forward
        , backward
        , toList
        , length
        )

{-| A `ZipList` is a collection which can be moved forward/backward and that exposes a single current element


# ZipLists

@docs ZipList


# Creation

@docs fromList, singleton


# Consultation

@docs current, toList, length


# Moving

@docs forward, backward

-}

import Maybe


{-| A collection data type that can be moved forward/backward and that exposes a current element (see the `current` function)
-}
type ZipList a
    = Empty
    | Zipper (List a) a (List a)


{-| Craft a new ZipList out of a List
-}
fromList : List a -> ZipList a
fromList list =
    case list of
        [] ->
            Empty

        head :: queue ->
            Zipper [] head queue


{-| Create a new ZipList with a single element in it
-}
singleton : a -> ZipList a
singleton item =
    Zipper [] item []


{-| Return the current element of a ZipList. `Nothing` will be returned if the ziplist is empty
-}
current : ZipList a -> Maybe a
current zipList =
    case zipList of
        Empty ->
            Nothing

        Zipper _ current _ ->
            Just current


performIfNonEmpty : (List a -> a -> List a -> ZipList a) -> ZipList a -> ZipList a
performIfNonEmpty f zipList =
    case zipList of
        Empty ->
            zipList

        Zipper before current after ->
            f before current after


{-| Move forward a `ZipList`
-}
forward : ZipList a -> ZipList a
forward zipList =
    performIfNonEmpty
        (\before current after ->
            case after of
                [] ->
                    Zipper before current after

                head :: queue ->
                    Zipper (current :: before) head queue
        )
        zipList


{-| Move backward a `ZipList`
-}
backward : ZipList a -> ZipList a
backward zipList =
    performIfNonEmpty
        (\before current after ->
            case before of
                [] ->
                    Zipper before current after

                head :: queue ->
                    Zipper queue head (current :: after)
        )
        zipList


{-| Convert a `ZipList` into a `List`
-}
toList : ZipList a -> List a
toList zipList =
    case zipList of
        Empty ->
            []

        Zipper before current after ->
            List.concat
                [ List.reverse before
                , [ current ]
                , after
                ]


{-| Return a `ZipList` length
-}
length : ZipList a -> Int
length zipList =
    case zipList of
        Empty ->
            0

        Zipper before _ after ->
            1 + (List.length before) + (List.length after)