Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add couple of potentially useful functions #3

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 52 additions & 10 deletions src/SelectList.elm
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
module SelectList
exposing
( SelectList
( Position(..)
, SelectList
, after
, append
, before
, decoder
, fromList
, fromLists
, map
, mapBy
, Position(..)
, fromLists
, select
, prepend
, append
, before
, after
, select
, selected
, toList
, singleton
, toList
)

{-| A `SelectList` is a nonempty list which always has exactly one element selected.

It is an example of a list [zipper](https://en.wikipedia.org/wiki/Zipper_(data_structure)).

@docs SelectList, fromLists, singleton
@docs SelectList, fromLists, fromList, singleton


## Reading
Expand All @@ -31,8 +33,15 @@ It is an example of a list [zipper](https://en.wikipedia.org/wiki/Zipper_(data_s

@docs map, mapBy, Position, select, append, prepend


## Decoding

@docs decoder

-}

import Json.Decode


{-| A nonempty list which always has exactly one element selected.

Expand Down Expand Up @@ -171,6 +180,22 @@ fromLists =
SelectList


{-| -}
fromList : List a -> Maybe (SelectList a)
fromList list =
let
( maybeHead, maybeTail ) =
( List.head list, List.tail list )
in
Maybe.map2
(\head ->
\tail ->
fromLists [] head tail
)
maybeHead
maybeTail


{-| Change the selected element to the first one which passes a
predicate function. If no elements pass, the `SelectList` is unchanged.

Expand Down Expand Up @@ -217,7 +242,7 @@ selectHelp isSelectable beforeList selectedElem afterList =

( first :: rest, _ ) ->
if isSelectable first then
Just ( [], first, (rest ++ selectedElem :: afterList) )
Just ( [], first, rest ++ selectedElem :: afterList )
else
case selectHelp isSelectable rest selectedElem afterList of
Nothing ->
Expand Down Expand Up @@ -270,3 +295,20 @@ prepend list (SelectList beforeSel sel afterSel) =
toList : SelectList a -> List a
toList (SelectList beforeSel sel afterSel) =
beforeSel ++ sel :: afterSel


{-| -}
decoder : Json.Decode.Decoder a -> Json.Decode.Decoder (SelectList a)
decoder itemDecoder =
let
createSelectList =
\list ->
case fromList list of
Just selectList ->
Json.Decode.succeed selectList

Nothing ->
Json.Decode.fail "expected list with more than one element"
in
Json.Decode.list itemDecoder
|> Json.Decode.andThen createSelectList