Kotlin prepend element - list

I am searching for Kotlin alternative to:
(cons 1 '(2 3)) in lisp or
1 : [2, 3] in haskell or
1 :: List(2, 3) in scala,
(which all result in sth like [1, 2, 3])
so I can prepend an element to a List<T> (or any other list you can offer).
It will also be fine if one could provide O(1) head and tail Kotlin alternatives (I've found just first())

I think the easiest would be to write:
var list = listOf(2,3)
println(list) // [2, 3]
list = listOf(1) + list
println(list) // [1, 2, 3]
There is no specific tail implementation, but you can call .drop(1) to get the same. You can make this head\tail more generic by writing these extension properties:
val <T> List<T>.tail: List<T>
get() = drop(1)
val <T> List<T>.head: T
get() = first()
Then:
val list = listOf(1, 2, 3)
val head = list.head
val tail = list.tail
Some more info: Kotlin List tail function

Any class which implements Deque will suitable for you, for example LinkedList:
val linkedList = LinkedList(listOf(2, 3))
linkedList.push(1)
println(linkedList) // [1, 2, 3]
Creating lists throught constructor LinkedList(listOf(2, 3)) in many places can be annoying, so feel free to write factory method:
fun <T> linkedListOf(vararg elements: T): LinkedList<T> {
return LinkedList<T>(elements.toList())
}
// Usage:
val list = linkedListOf(2, 3)
list.push(1)
println(list) // [1, 2, 3]

Simple, just wrap the element to prepend in a List and then use the + operator (or List.plus()) to concatenate the two Lists:
val list1 = listOf(2, 3) // [2, 3]
val list2 = listOf(1) + list1 // [1, 2, 3]
For your second question, in Kotlin 1.2 there are:
List.first()
List.last()
Both are O(1)

This could be done easily with extension functions as below
Prepending element
fun <T> MutableList<T>.prepend(element: T) {
add(0, element)
}
Prepending list
fun <T> MutableList<T>.prependAll(elements: List<T>) {
addAll(0, elements)
}

Inserts an element into the list at the specified index.
abstract fun add(index: Int, element: E)
Thus answer is
list.add(0,element)

If you do that often in your code for some reason, consider adding an extension operator method such as:
operator fun <T> T.plus(tail: List<T>): List<T> {
val list = ArrayList<T>(1 + tail.size)
list.add(this)
list.addAll(tail)
return list
}
Then your code could work Scala-like: 1 + listOf(2, 3)
Another way to achieve the same behaviour, shorter but sacrifices some memory:
operator fun <T> T.plus(tail: List<T>): List<T> {
return mutableListOf(this).apply {
addAll(tail)
}
}

To be as close to Lisp as possible consider using immutable linked list.
You can use pcollections
val list = ConsPStack.from(listOf(2, 3))
val newList = list + 1
println(list) // [2, 3]
println(newList) // [1, 2, 3]
Head:
list.first() // 1
list[0] // 1
(unfortunately this thing needs one allocation)
Tail:
list - 0 // [2, 3]
list.subList(1) // [2, 3]
Looks rather ugly.
Hopefully we'll get better API when kotlinx.collections.immutable will be ready. It's an effort to create standard Kotlin immutable collections (not just read-only ones that we currently have). As of now this project is still at very early stage (I was unable to find structure that supports efficient prepend/head/tail there)

I'm not entirely sure what you want to do, so please try one of the following.
Mutating list:
val list = mutableListOf(3, 2)
list.add(1)
Copping an immutable list:
var list = listOf(3, 2)
list = list + 1

Related

Pattern match against List 'init' and 'last' instead of 'head' and 'tail'

I know that it's possible to easily pattern match against the head (or an arbitrary number of initial elements) and tail of a List:
val items = List(1, 2, 3, 4)
val first :: rest = items
println(first, rest) // 1, List(2, 3, 4)
However, I would like to do it the other way - can you use a pattern to get the init and last of the list?
val items = List(1, 2, 3, 4)
val rest ??? last = items
println(rest, last) // List(1, 2, 3), 4
In JavaScript this would look like:
const [...init, last] = items
You can use the :+ custom extractor object.
So the code would look like this:
val rest :+ last = items
However, note that this is equally inefficient than doing:
val last :: rest = items.reverse
But, if you then need to decompose rest again, then reversing it first will be more efficient.
Finally, remember both are unsafe since they will throw in case the List is empty.
This should work:
val xs :+ x = items
Check out: https://www.scala-lang.org/files/archive/api/2.12.0/scala/collection/Seq.html#:+(elem:A):Seq[A]

Append Maybe to List in Elm

I have a List a and a Maybe a. I want to append the maybe value if it is Just a but do nothing if it is Nothing.
This is what I am currently using:
aList ++ case maybeValue of
Just value ->
[ value ]
Nothing ->
[]
Is there a better (more idiomatic) way of doing this?
Note that prepending is fine too if there is a cleaner way of doing that instead. The list order does not matter.
From Chad's suggestion that prepending is cheaper:
prependMaybe : List a -> Maybe a -> List a
prependMaybe list maybe =
case maybe of
Just value ->
value :: list
Nothing ->
list
I think you can use Maybe.map List.singleton yourMaybe |> Maybe.withDefault [].
Here you have a complete example:
appendMaybe : List a -> Maybe a -> List a
appendMaybe list maybe =
Maybe.map List.singleton maybe
|> Maybe.withDefault []
|> (++) list
You can try it on Ellie
If you're going for conciseness, you could use Maybe.Extra.unwrap from the elm-community/maybe-extra package:
import Maybe.Extra exposing (unwrap)
consMaybe : List a -> Maybe a -> List a
consMaybe list =
unwrap list (flip (::) list)
appendMaybe : List a -> Maybe a -> List a
appendMaybe list =
unwrap list ((++) list << List.singleton)
If you really want to go crazy, you can create your own infix operators:
infixr 5 ::?
(::?) = flip consMaybe
infixr 5 ++?
(++?) = appendMaybe
This allows the following:
Nothing ::? [2, 3, 4] == [2, 3, 4]
Just 1 ::? [2, 3, 4] == [1, 2, 3, 4]
[2, 3, 4] ++? Nothing == [2, 3, 4]
[2, 3, 4] ++? Just 5 == [2, 3, 4, 5]
Now, whether the infix versions are idiomatic Elm, that's up for debate. If it's something you use a lot, perhaps it's worth it, but most Elm guides urge you to avoid infix operators because they hinder discoverability.
In the end, your original example has the benefit of being readable and probably more readily understandable, since fewer people will be familiar with unwrap. The only suggestion would be that if order truly doesn't matter, then prepending an item to a list is going to be faster than concatenating lists.

groovy: adding and removing elements from a defined variable within a class

I'm trying to get this class to run but I keep running into issues. I'm new to Java and not sure if I am doing this correctly. If someone could just help me out with the addition of elements to a list I can figure out the rest!
class ListPractice implements Testable {
def mylist = [4,5,6]
/**
* Adds a set of elements to the mylist variable
*
* #param elts The elements to be added
*/
def addToList(List elts) {
def newlist = getMylist()+List
return newlist
}
#Override
void testMe() {
addToList([7,8,9])
assert getMylist() == [4,5,6,7,8,9]
assert getMylist() == [7,8,9]
}
}
You are adding List instead of elts. The method you are looking for is addAll:
groovy:000> l = [1,2,3]
===> [1, 2, 3]
groovy:000> l.addAll([4,5,6])
===> true
groovy:000> l
===> [1, 2, 3, 4, 5, 6]
Since addtoList sounds already as if you plan to mutate this, why create a
new one, return it, and later never use it? So: mylist.addAll(elts) should
be enough.
related:
just write mylist instead of getMylist() - it's groovy
your comment on addToList says set but accepys a list. Sets have
different characteristics than lists, so it's confusing. If you rename it
to addToMylist you might not even need a comment at all.

Does SML supports the nested list?

the Nested List can exist in Scheme, but is it legal to use nested-list in SML? or we can only use simple list in SML?
and if legal,
1) how to check wether the two input list have the same list structure. algorithm the atoms in the list are not equal.
2) Whatever the deep of the input list, how to delete all the atoms in the nested-list that equals to the input value: a. should use the original list and not create a new list.
There's no problem in having nested lists in Standard ML. For an example:
val foo = [ [1, 2, 3], [4, 5], [6] ]
is an example of an int list list, i.e., a list of lists of integers.
As for your additional questions.
1
If by same structure you mean whether the sublists contain the same number of elements, i.e, you want
val bar = [ [34, 4, 6], [2, 78], [22] ]
val baz = [ [1], [4, 6, 2], [3, 6] ]
val cmp_foo_bar = structureEq (foo, bar) (* gives true, since the lengths of the sublists match up *)
val cmp_foo_baz = structureEq (foo, baz) (* gives false, since they don't *)
Then you can simply make a recursive function on the lists, that compares the length of each sublist in turn.
Note, if the lists are nested more than once, you'll need a function for each level. (i.e., one for 'a list lists, one for 'a list list lists, etc.
2
You cannot make a function that "however deep the input list" does something to the elements in the list. The type system will not let you do this. This is similar to how you cannot make the following list:
val illegal_list = [ [1, 2], [ [1, 4], [2, 3] ] ]
This is due to a list only being allowed to contain one type of elements, so if you have an 'a list list, each element in the list must be an 'a list. You cannot have 'as directly.
You'll have to settle on how nested the lists are, and make a function specific to that depth.
There is no problem with nesting lists in SML, e.g. [[1, 2], [3, 4]] works just fine.
However, I suspect you actually mean something more general, namely the ability to nest "lists" in heterogeneous ways: [[1, [3]], 2]. This is not legal as such in SML. However, this is because such a thing is not really a list, it is a tree.
You can define trees easily as well, but you need a more general type definition than the one for list:
datatype 'a tree = L of 'a | T of 'a tree list
Then T[T[L 1, T[L 3]], L 2] is a representation of the "list" above. A function for computing the depth (or height) of such a tree looks like
fun depth (L _) = 0
| depth (T ts) = 1 + max (List.map depth ts)
where max needs to be defined in the obvious manner.

How to flatten a nested list in Vim script?

I found some Vim list functions can not work as I thought.
For example:
let list0 = [1, [1, 2]]
echo count(list0, 1)
It returns 1, but I want it returns 2. So I think those functions can not deep into nested lists, only work on first level.
I think here I should expand nested list into a normal list like this:
list0 = [1, 1, 2]
How to flatten a nested list?
" Code from bairui##vim.freenode
" https://gist.github.com/3322468
function! Flatten(list)
let val = []
for elem in a:list
if type(elem) == type([])
call extend(val, Flatten(elem))
else
call add(val, elem)
endif
unlet elem
endfor
return val
endfunction
Here unlet elem is necessary. Because the elem variable is changing, it is a list item, or a list, and VimL does not support assign a list item to a list, and vice versa.
You can use reduce() since 8.2.0878:
let mylist = [[1, 2], [3, 4], 5]
echo reduce(mylist, { acc, val -> type(val) == 3 ? extend(acc, val) : add(acc, val)})
outputs:
[1, 2, 3, 4, 5]
I suggest vital.vim's Data.List.flatten as an another answer ;D
https://github.com/vim-jp/vital.vim