Holmusk / elm-street

:deciduous_tree: Crossing the road between Haskell and Elm
Mozilla Public License 2.0
88 stars 6 forks source link

Elm instance for NonEmpty #102

Closed googleson78 closed 2 years ago

googleson78 commented 4 years ago

It's great that NonEmpty has an Elm instance, but the instance uses ordinary elm lists, losing whatever guarantees I wanted to have in Haskell.

Would it be worth it to also implicitly depend on something like this package, telling people that if they want to use NonEmpty they also need to install it?

I would personally be fine with the tradeoff. I also didn't find other "nonempty list" packages for elm

ShrykeWindgrace commented 4 years ago

@googleson78 There is also https://package.elm-lang.org/packages/hrldcpr/elm-cons/latest/Cons for nonempty lists.

turboMaCk commented 4 years ago

I would recommend using simple (a, List a) as a representation for non empty.

googleson78 commented 4 years ago

Why work with raw tuples when you can have a record or even a custom type?

turboMaCk commented 4 years ago

Record

Record would be fine but doesn't really provide much additional value.

type alias NonEmptyList a = { head : a, tail : List a }

names of fields are indeed descriptive but in fact in this case exactly the same information is already expressed by type. Head must be of type a, tail must be of type List a

Compatibility with existing code

Many widely used libraries like list-extra are using tuples already for some of the functions. Using tuple would mean out of the box compatibility with those functions. example

Custom Type

There are some implementations of as a 3rd party packages that could be used but I don't personally feel any of them complete enough to be considered standard. There are also several implementations of Zipper for list which, in my opinion at least, should be in fact defined in terms of non empty list. Not as a List zipper but rather as a non empty list with zipper. With all the goodies like Comonad functions. Also this would mean imposing yet another dependency on users.

Defining own type would also mean no out of the box compatibility with existing nonempty-list implementations and zippers.

Using Tuple

More people share this opinion

googleson78 commented 4 years ago

Re elm's list-extra:

Just because right now there might be something you feel is incomplete doesn't mean that we should settle on an imperfect (imo) solution which exposes implementation details to a user:

(in the thread you linked there are also lots of people preferring the NonEmpty version)

In any case it seems that for something like this to happen, a NonEmpty needs to exist in elms core, so that there need to be no additional/incomplete/non-canonic libraries required.

turboMaCk commented 4 years ago

I agree with you - You should not care about the fact that non empty list is implemented as tuple. Expected usecase would be to define custom function (a, List a) -> NonEmpty a which can be easily done for what ever implementation of NonEmpty you decide to use. It's also possible to implement package where NonEmpty type is an alias to this pair.

exposes implementation details to a user

Even implementation using custom variant exposes its constructors. But I would agree with trade-off in expressiveness. With alias there would be NonEmpty in a types (even though interchangable with tuple) but there wouldn't be explicit NonEmpty constructor in value space. I agree this is downside of such approach.

(in the thread you linked there are also lots of people preferring the NonEmpty version)

Yes indeed. My additional point would be that base has Data.List.NonEmpty so it's just a matter of importing that module. In elm though, 3rd party package is needed.

I'm basing this suggestion on my personal experience working on app where we used both mgold/elm-nonempty-list and wernerdegroot/listzipper and I always felt there are some negative implications from this fragmentation.

Take this as my personal suggestion and nothing more.

turboMaCk commented 4 years ago

For the record I've published package which defines non empty list as an alias to pair (a, List a)

https://package.elm-lang.org/packages/turboMaCk/non-empty-list-alias

turboMaCk commented 2 years ago

issue is resolved by merge of https://github.com/Holmusk/elm-street/pull/105

new version of library is not released yet. But it will be eventually released once we batch together more improvements.