Code Monkey home page Code Monkey logo

non-empty-list-alias's Introduction

List.NonEmpty alias with Zipper

Build Status

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

Implementation of non-empty list defined as alias to pair (a, List a). This means that producing or consuming type compatible with this library doesn't require having it as a dependency. Apart from this, this package aims to provide the most feature complete implementation of non-empty list for Elm and includes variety of practical functions from JSON decoder helpers to hi-level combinators like duplicate and extend.

Motivation

elm/core doesn't come with non empty list type. This means one usually has to rely on library implementation of NonEmpty type:

These implementations usually define custom data type similar to NonEmpty a = Cons a (List a) and expose the constructor to make pattern matching possible. 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 onto their users.

This library takes different approach. NonEmpty is an alias for the pair type alias NonEmpty a = (a, List a). Relying on anonymous data-type like tuple means:

  1. Libraries can produce NonEmpty data without depending on specific (including this) implementation.
  2. Implementation provided by this package can be easily replaced by different implementation using the same type definition.
  3. Users may choose to work with tuple directly without need to transform from and to NonEmpty type.

Zipper

One of the downsides of common approach is also noticeable with available list zipper implementations.

All of above are usually constructed using List a -> Maybe (Zipper a) without possibility to construct zipper as NonEmpty a -> Zipper a. The motivation behind including Zipper in this package is to encourage its usage together with NonEmpty list. My favorite implementation of list zipper which doesn't rely on NonEmpty is zwilias/elm-holey-zipper.

Drawbacks

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

conventional library:

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

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

Maybe.NonEmpty provides traversing functions between Maybes and List.NonEmpty.

non-empty-list-alias's People

Contributors

jfmengels avatar jhrcek avatar kraklin avatar kubaracek avatar kurren123 avatar kutyel avatar siriusstarr avatar turbomack avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

non-empty-list-alias's Issues

Add `List.NonEmpty.partition/unique` ?

Hi!

We (GWI) recently switched internally to use this library instead of our custom one (after finding a bug in our implementation ๐Ÿ˜“) and the only two functions missing are partition and unique. I fallback to the inner List and applied the List.Extra functions but maybe there is a better way to implement them?

Either way if you consider these two useful for this package I can provide a PR myself ๐Ÿ˜„

Missing combine (sequence) function

Hi!

In some places in the GWI code we are using this function:

combine : NonemptyList (Maybe a) -> Maybe (NonemptyList a)
combine ( m, ms ) =
    Maybe.map2 fromCons m (Maybe.combine ms)

Would you agree that it is generally useful so that I can make a PR to this repo and add it? ๐Ÿ˜‰

(Also, there is a find function missing ๐Ÿค” )

Need a Zipper.set

Could also be called Zipper.update or something similar, but I need something which sets the current focus at the zipper, throwing away the old one. Something like:

set : a -> Zipper a -> Zipper a
set a (Zipper b f n) = 
    (Zipper b a n)

I can make do with Zipper.custom for now, but just thought I'd let you know. Happy to make a PR when I have a moment, let me know if you'd like that.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.