Closed jcnelson closed 3 years ago
This cannot be done in a library function, since the type of element-at is the type of the individual list item.
Good point. Writing something like this for each argument type would be a hassle:
(define-read-only (nth-reducer
(item int)
(state {n: int, result (optional int)}))
{n: (- (get n state) 1)
result: (if (is-eq (get n state) 1) (some item) (get result state))})
(define-read-only (nth (items (list 100 int)) (n int))
(unwrap-panic (get result (fold nth-reducer items {n: n, result: none}))))
(nth (list 1 2 3) 2) ;; returns the second item in the list
Here is a general implementation of nth
assuming proposal #41:
(define-private (nth-reducer item state)
{n: (- (get n state) 1)
result: (if (is-eq (get n state) 1) (some item) (get result state))})
(define-private (nth items n)
(unwrap-panic (get result (fold nth-reducer items {n: n, result: none}))))
(define-read-only (foo)
(nth (list 1 2 3) 2))
I suggest reconsidering the name of the function, proposing nth
as an alternative, as in:
(define-private (first items)
(nth items 1))
(define-private (second items)
(nth items 2))
(define-private (last items)
(nth items (len items)))
This happened.
This cannot be done in a library function, since the type of
element-at
is the type of the individual list item. Implementingelement-at
for each type in a contract not only duplicates a lot of code, but is also inefficient, since it requires a O(n)fold
to be applied to the list.