Implementation of NonEmptyList - List with at least 1 element
NonEmptyList implements kotlin.List interface and can be used anywhere where you use kotlin.List or java.lang.List
Sometimes you have code that expects list with at least one element and empty list considered as illegal argument.
Problem that you cannot force user of your API to use only non empty lists using Kotlin (or Java/JS/C) type system.
Possible solution: introduce special type that represents list with at least one element. So now compiler can check correct usage of your API and no need to check.
This library provides such type: NonEmptyList
NonEmptyList
is subtype of kotlin.List
and can be used as any other list.
But if you use NonEmptyList
in your API you force use of this API to use NonEmptyList
so non need
NonEmptyList<T>
interface contains two additional properties:
head: T
- first element of a list. Can be null if generic type of NonEmptyList is nullable.
Use this property instead of first()
or get[0]
because it's always safe to use head
.
tail: List<T>
- all elements of a list excluding first one.
Cannot be null, but can be empty (for list with only one element)
You have a few ways to create NonEmptyList instance.
Implementations of NonEmptyList are private, but you can use these builder functions:
nelOf(head: T)
and NonEmptyList(head: T)
- instance with 1 element.
Implementation is optimized and uses single element list implementation under the hood.
nelOf(head: T, vararg tail: T): NonEmptyListT>
- creates instance from head and array of varargs
NonEmptyList(head: T, tail: List<T>)
- creates instance from head and tail list.
For tail will be created defencive copy on creation
List<T>.toNel(): NonEmptyList<T>?
- converts existing list to NonEmptyList. Returns null if original list is empty
List<T>.toNelUnsafe(): NonEmptyList<T>
- convert existing list to NonEmptyList.
Throws NoSuchElementException
if original list is empty.
Use this builder only as assert and try to use other builders if it's possible.
Type alias Nel
is available for NonEmptyList
.
It's relatively common abbreviation that allows to define type in much more short way.
But there is no builder functions for Nel
like for NonEmptyList
,
so use NonEmptyList
or nelOf
instead.
If you think that such inconsistency of API is something bad, be free to open issue it can be reconsidered.
Interface and all implementations of NonEmptyList
are read-only,
but for simplicity and performance we don't create defencive copy of tail
on read,
so on JVM NonEmptyList
is not really immutable and as all Kotlin collections just read-only.
If you need real immutable list, create NonEmptyList using builder function:
NonEmptyList(head: T, tail: List<T>)
and pass real immutable implementation to tail param.
On JVM you can use java.util.Collections.unmodifiableList
Arrow - functional library for Kotlin has own implementation of NonEmptyList.
But this implementation is not subtype of List
and provide more functional approach.
If you already use Arrow
on your project just keep using it.
But if you just want to make your code little bit more type safe and do not use Arrow, you can use this library.
Copyright 2018 Andrey Mischenko
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.