turboMaCk/non-empty-list-alias/1.0.0

NOTE: the latest version is 1.4.0

List.NonEmpty alias with Zipper

Build Status

Work in progress

Functions for NonEmptyList you already have and Zipper implementation that goes with it.

This implementation of non-empty list is using alias to pair (a, List a) so comparible type can be produced without dependecy on this library. Despite this, this package aims to provide the most feature complete implementation of NonEmptyList for Elm and includes variety of practical functions like Json decoder as well as high level combinators like duplicate and extend.

Motivation

elm/core doesn't come with any sort of NoneEmptyList type. This means one usually has to reply on one of the user implementations on NonEmpty type:

These implementations usually define custom type like NonEmpty a = Cons a (List a) and expose the constructor to make pattern matching possible. Anyway this makes it hard for library authors to provide support for NonEmpty because they would need to pick one of these libraries and use it as a dependency of their own implementation and essentially impose this decision on their users.

This implementation uses different approach. NonEmpty is an alias on the pair type alias NonEmpty a = (a, List a). Relaying on anonymous data-type like tuple means:

  1. Libraries can produce NonEmpty data without depending on specific implementation
  2. Implementation provided by this package can be easily replaced by different implementation using same type.
  3. Users maye choose to work with tupple directly without need to tranform from and to NonEmpty type.

Zipper

One of the areas where downside of current approaches is already noticeable is when it comes to Zipper implementation.

All of which are usually constructed using List a -> Maybe (Zipper a) instead of NonEmpty a -> Zipper a. The motivation behind including Zipper is to encourage it's usage together with NonEmpty list. My favorite implementation of zipper which doesn't rely on NonEmpty is zwilias/elm-holey-zipper.

Drawbacks

Compare to other implementations this implementation has less descriptive constructor in value space. This means that in pattern matching happens on pair instead of explicit constructor like Cons or NonEmpty.

conventional library:

matchNonEmpty : NonEmptyList a -> foo
matchNonEmpty (Cons h t) =
    .....

With this library:

matchNonEmpty : NonEmptyList a -> foo
matchNonEmpty (h, t) =
    .....

For Haskell Fanbois

List.NoneEmpty.NonEmpty is:

  • Functor
  • Foldable
  • Applicative
  • Monad
  • Comonad

List.NonEmpty.Zipper is:

  • Functor
  • Foldable
  • Applicative
  • Comonad