diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..5fc26cf8 --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ + +default: main +.PHONY: default + +include $(PUREC_DIR)/mk/target.mk + +SHELL := /bin/bash +srcs := src test +deps := bower_components/purescript-*/src +$(eval $(call purs_mk_target,main,Test.Main,$(srcs),$(deps))) diff --git a/src/Data/Array.c b/src/Data/Array.c new file mode 100644 index 00000000..7d3f7f10 --- /dev/null +++ b/src/Data/Array.c @@ -0,0 +1,314 @@ +#include + +//------------------------------------------------------------------------------ +// Array creation -------------------------------------------------------------- +//------------------------------------------------------------------------------ + +PURS_FFI_FUNC_2(Data_Array_range, _start, _end, { + const purs_any_int_t start = purs_any_get_int(_start); + const purs_any_int_t end = purs_any_get_int(_end); + purs_any_int_t step = start > end ? -1 : 1; + purs_vec_t * result = (purs_vec_t *) purs_vec_new(); + purs_any_int_t i = start; + while (i != end) { + purs_vec_push_mut(result, purs_any_int_new(i)); + i += step; + } + purs_vec_push_mut(result, purs_any_int_new(i)); + return purs_any_array_new(result); +}); + +PURS_FFI_FUNC_2(Data_Array_replicate, _count, value, { + const purs_any_int_t count = purs_any_get_int(_count); + purs_vec_t * result = (purs_vec_t *) purs_vec_new(); + for (purs_any_int_t i = 0; i < count; i++) { + purs_vec_push_mut(result, value); + } + return purs_any_array_new(result); +}); + +PURS_FFI_FUNC_2(Data_Array_curryCons, head, tail, { + return purs_any_record_new( + purs_record_new_from_kvps(2, "head", head, "tail", tail)); +}); + +PURS_FFI_FUNC_1(Data_Array_listToArray, list, { + purs_vec_t * result = (purs_vec_t *) purs_vec_new(); + purs_any_t * xs = (purs_any_t *) list; + while (xs != NULL) { + const purs_record_t * record = purs_any_get_record(xs); + const purs_any_t * head = purs_record_find_by_key(record, "head")->value; + const purs_any_t * tail = purs_record_find_by_key(record, "tail")->value; + purs_vec_push_mut(result, head); + xs = (purs_any_t *) tail; + } + return purs_any_array_new(result); +}); + +PURS_FFI_FUNC_2(Data_Array_fromFoldableImpl, foldr, xs, { + return purs_any_app(Data_Array_listToArray$, + purs_any_app( + purs_any_app( + purs_any_app(foldr, Data_Array_curryCons$), + NULL + ), + xs + ) + ); +}); + +//------------------------------------------------------------------------------ +// Array size ------------------------------------------------------------------ +//------------------------------------------------------------------------------ + +PURS_FFI_FUNC_1(Data_Array_length, _xs, { + const purs_vec_t * xs = purs_any_get_array(_xs); + return purs_any_int_new(xs->length); +}); + +//------------------------------------------------------------------------------ +// Extending arrays ------------------------------------------------------------ +//------------------------------------------------------------------------------ + +PURS_FFI_FUNC_2(Data_Array_cons, e, l, { + return purs_any_array_new(purs_vec_insert(purs_any_get_array(l), 0, e)); +}); + +PURS_FFI_FUNC_2(Data_Array_snoc, _l, e, { + const purs_vec_t * l = purs_any_get_array(_l); + return purs_any_array_new(purs_vec_insert(l, l->length, e)); +}); + +//------------------------------------------------------------------------------ +// Non-indexed reads ----------------------------------------------------------- +//------------------------------------------------------------------------------ + +PURS_FFI_FUNC_3(Data_Array_uncons$, empty, next, _xs, { + const purs_vec_t * xs = purs_any_get_array(_xs); + if (xs->length == 0) { + return purs_any_app(empty, NULL); + } else { + return purs_any_app(purs_any_app(next, xs->data[0]), purs_any_array_new(purs_vec_slice(xs, 1))); + } +}); + +//------------------------------------------------------------------------------ +// Indexed operations ---------------------------------------------------------- +//------------------------------------------------------------------------------ + +PURS_FFI_FUNC_4(Data_Array_indexImpl, just, nothing, _xs, _i, { + const purs_any_int_t i = purs_any_get_int(_i); + const purs_vec_t * xs = purs_any_get_array(_xs); + if (i < 0 || i >= xs->length) { + return nothing; + } else { + return purs_any_app(just, xs->data[i]); + } +}); + +PURS_FFI_FUNC_4(Data_Array_findIndexImpl, just, nothing, f, _xs, { + const purs_vec_t * xs = purs_any_get_array(_xs); + for (purs_any_int_t i = 0; i < xs->length; i++) { + if (purs_any_app(f, xs->data[i]) == purs_any_true) { + return purs_any_app(just, purs_any_int_new(i)); + } + } + return nothing; +}); + +PURS_FFI_FUNC_4(Data_Array_findLastIndexImpl, just, nothing, f, _xs, { + const purs_vec_t * xs = purs_any_get_array(_xs); + for (purs_any_int_t i = xs->length - 1; i >= 0; i--) { + if (purs_any_app(f, xs->data[i]) == purs_any_true) { + return purs_any_app(just, purs_any_int_new(i)); + } + } + return nothing; +}); + +PURS_FFI_FUNC_5(Data_Array__insertAt, just, nothing, _i, a, _l, { + const purs_any_int_t i = purs_any_get_int(_i); + const purs_vec_t * l = purs_any_get_array(_l); + if (i < 0 || i > l->length) { + return nothing; + } + return purs_any_app(just, purs_any_array_new(purs_vec_insert(l, i, a))); +}); + +PURS_FFI_FUNC_4(Data_Array__deleteAt, just, nothing, _i, _l, { + const purs_any_int_t i = purs_any_get_int(_i); + const purs_vec_t * l = purs_any_get_array(_l); + if (i < 0 || i >= l->length) { + return nothing; + } + purs_vec_t * l1 = (purs_vec_t *) purs_vec_copy(l); + vec_splice(l1, i, 1); + return purs_any_app(just, purs_any_array_new(l1)); +}); + +PURS_FFI_FUNC_5(Data_Array__updateAt, just, nothing, _i, a, _l, { + const purs_any_int_t i = purs_any_get_int(_i); + const purs_vec_t * l = purs_any_get_array(_l); + if (i < 0 || i >= l->length) { + return nothing; + } + purs_vec_t * l1 = (purs_vec_t *) purs_vec_copy(l); + l1->data[i] = a; + return purs_any_app(just, purs_any_array_new(l1)); +}); + +//------------------------------------------------------------------------------ +// Transformations ------------------------------------------------------------- +//------------------------------------------------------------------------------ + +PURS_FFI_FUNC_1(Data_Array_reverse, _l, { + const purs_vec_t * l = purs_any_get_array(_l); + purs_vec_t * result = (purs_vec_t *) purs_vec_new(); + for (purs_any_int_t i = l -> length - 1; i >= 0; i--) { + purs_vec_push_mut(result, l->data[i]); + } + return purs_any_array_new(result); +}); + +PURS_FFI_FUNC_1(Data_Array_concat, xss, { + purs_any_int_t i; + purs_any_int_t j; + const purs_any_t * xs; + const purs_any_t * tmp; + purs_vec_t * result = (purs_vec_t *) purs_vec_new(); + purs_vec_foreach(purs_any_get_array(xss), xs, i) { + purs_vec_foreach(purs_any_get_array(xs), tmp, j) { + purs_vec_push_mut(result, tmp); + } + } + return purs_any_array_new(result); +}); + +PURS_FFI_FUNC_2(Data_Array_filter, f, xs, { + const purs_any_t * tmp; + purs_any_int_t i; + purs_vec_t * result = (purs_vec_t *) purs_vec_new(); + purs_vec_foreach(purs_any_get_array(xs), tmp, i) { + if (purs_any_app(f, tmp) == purs_any_true) { + purs_vec_push_mut(result, tmp); + } + } + return purs_any_array_new(result); +}); + +PURS_FFI_FUNC_2(Data_Array_partition, f, xs, { + purs_vec_t * yes = (purs_vec_t *) purs_vec_new(); + purs_vec_t * no = (purs_vec_t *) purs_vec_new(); + purs_any_int_t i; + const purs_any_t * tmp; + purs_vec_foreach(purs_any_get_array(xs), tmp, i) { + if (purs_any_app(f, tmp) == purs_any_true) { + purs_vec_push_mut(yes, tmp); + } else { + purs_vec_push_mut(no, tmp); + } + } + return purs_any_record_new( + purs_record_new_from_kvps(2, + "yes", purs_any_array_new(yes), + "no", purs_any_array_new(no))); +}); + +//------------------------------------------------------------------------------ +// Sorting --------------------------------------------------------------------- +//------------------------------------------------------------------------------ + +PURS_FFI_FUNC_2(Data_Array_sortImpl, f, _l, { + purs_vec_t * l = (purs_vec_t *) purs_vec_copy(purs_any_get_array(_l)); + purs_any_int_t i; + purs_any_int_t j; + purs_any_int_t swapped; + const purs_any_t * tmp; + + for (i = 0; i < l->length-1; i++) { + swapped = 0; + for (j = 0; j < l->length-i-1; j++) { + const purs_any_t * r = purs_any_app(purs_any_app(f, l->data[j]), l->data[j+1]); + if (purs_any_get_int(r) > 0) { + tmp = l->data[j]; + l->data[j] = l->data[j+1]; + l->data[j+1] = tmp; + swapped = 1; + } + } + + // IF no two elements were swapped by inner loop, then break + if (swapped == 0) { + break; + } + } + + return purs_any_array_new(l); +}); + +//------------------------------------------------------------------------------ +// Subarrays ------------------------------------------------------------------- +//------------------------------------------------------------------------------ + +PURS_FFI_FUNC_3(Data_Array_slice, _s, _e, _l, { + const purs_any_int_t s = purs_any_get_int(_s); + const purs_any_int_t e = purs_any_get_int(_e); + const purs_vec_t * l = purs_any_get_array(_l); + purs_vec_t * out = (purs_vec_t *) purs_vec_new(); + for (purs_any_int_t i = s; i < e; i ++) { + if (i >= 0 && i < l->length) { + purs_vec_push_mut(out, l->data[i]); + } + } + return purs_any_array_new(out); +}); + +PURS_FFI_FUNC_2(Data_Array_take, _n, _l, { + const purs_any_int_t n = purs_any_get_int(_n); + const purs_vec_t * l = purs_any_get_array(_l); + purs_vec_t * out = (purs_vec_t *) purs_vec_new(); + for (purs_any_int_t i = 0; i < n; i ++) { + if (i >= 0 && i < l->length) { + purs_vec_push_mut(out, l->data[i]); + } + } + return purs_any_array_new(out); +}); + +PURS_FFI_FUNC_2(Data_Array_drop, _n, _l, { + const purs_any_int_t n = purs_any_get_int(_n); + const purs_vec_t * l = purs_any_get_array(_l); + if (n < 1) { + return _l; + } + purs_vec_t * out = (purs_vec_t *) purs_vec_new(); + for (purs_any_int_t i = n; i < l->length; i++) { + purs_vec_push_mut(out, l->data[i]); + } + return purs_any_array_new(out); +}); + +//------------------------------------------------------------------------------ +// Zipping --------------------------------------------------------------------- +//------------------------------------------------------------------------------ + +PURS_FFI_FUNC_3(Data_Array_zipWith, f, _xs, _ys, { + const purs_vec_t * xs = purs_any_get_array(_xs); + const purs_vec_t * ys = purs_any_get_array(_ys); + purs_any_int_t l = xs->length < ys->length ? xs->length : ys->length; + purs_vec_t * out = (purs_vec_t *) purs_vec_new(); + for (purs_any_int_t i = 0; i < l; i++) { + purs_vec_push_mut(out, purs_any_app(purs_any_app(f, xs->data[i]), ys->data[i])); + } + return purs_any_array_new(out); +}); + +//------------------------------------------------------------------------------ +// Partial --------------------------------------------------------------------- +//------------------------------------------------------------------------------ + +PURS_FFI_FUNC_2(Data_Array_unsafeIndexImpl, _xs, _n, { + const purs_vec_t * xs = purs_any_get_array(_xs); + const purs_any_int_t n = purs_any_get_int(_n); + return xs->data[n]; +}); diff --git a/src/Data/Array.h b/src/Data/Array.h new file mode 100644 index 00000000..6a3a1162 --- /dev/null +++ b/src/Data/Array.h @@ -0,0 +1,30 @@ +#ifndef Data_Array_H +#define Data_Array_H + +#include + +PURS_FFI_EXPORT(Data_Array_range); +PURS_FFI_EXPORT(Data_Array_replicate); +PURS_FFI_EXPORT(Data_Array_fromFoldableImpl); +PURS_FFI_EXPORT(Data_Array_length); +PURS_FFI_EXPORT(Data_Array_cons); +PURS_FFI_EXPORT(Data_Array_snoc); +PURS_FFI_EXPORT(Data_Array_uncons$); +PURS_FFI_EXPORT(Data_Array_indexImpl); +PURS_FFI_EXPORT(Data_Array_findIndexImpl); +PURS_FFI_EXPORT(Data_Array_findLastIndexImpl); +PURS_FFI_EXPORT(Data_Array__insertAt); +PURS_FFI_EXPORT(Data_Array__deleteAt); +PURS_FFI_EXPORT(Data_Array__updateAt); +PURS_FFI_EXPORT(Data_Array_reverse); +PURS_FFI_EXPORT(Data_Array_concat); +PURS_FFI_EXPORT(Data_Array_filter); +PURS_FFI_EXPORT(Data_Array_partition); +PURS_FFI_EXPORT(Data_Array_sortImpl); +PURS_FFI_EXPORT(Data_Array_slice); +PURS_FFI_EXPORT(Data_Array_take); +PURS_FFI_EXPORT(Data_Array_drop); +PURS_FFI_EXPORT(Data_Array_zipWith); +PURS_FFI_EXPORT(Data_Array_unsafeIndexImpl); + +#endif // Data_Array_H diff --git a/src/Data/Array.purs b/src/Data/Array.purs index 9cdf06fe..d43d3a1d 100644 --- a/src/Data/Array.purs +++ b/src/Data/Array.purs @@ -866,8 +866,8 @@ groupBy op xs = iter <- STAI.iterator (xs !! _) STAI.iterate iter \x -> void do sub <- STA.empty - STAI.pushWhile (op x) iter sub _ <- STA.push x sub + STAI.pushWhile (op x) iter sub grp <- STA.unsafeFreeze sub STA.push ((unsafeCoerce :: Array ~> NonEmptyArray) grp) result STA.unsafeFreeze result diff --git a/src/Data/Array/NonEmpty/Internal.c b/src/Data/Array/NonEmpty/Internal.c new file mode 100644 index 00000000..471185eb --- /dev/null +++ b/src/Data/Array/NonEmpty/Internal.c @@ -0,0 +1,102 @@ +#include + +PURS_FFI_FUNC_2(Data_Array_NonEmpty_Internal_fold1Impl, f, _xs, { + const purs_vec_t * xs = purs_any_get_array(_xs); + const purs_any_t * acc = xs->data[0]; + for (purs_any_int_t i = 1; i < xs->length; i++) { + acc = purs_any_app(purs_any_app(f, acc), xs->data[i]); + } + return acc; +}); + +PURS_FFI_FUNC_1(Cont, fn, { + return purs_any_record_new( + purs_record_new_from_kvps(2, + "type", purs_any_string_new("Cont"), + "fn", fn)); +}); + +PURS_FFI_FUNC_1(finalCell, head, { + return purs_any_record_new( + purs_record_new_from_kvps(3, + "type", purs_any_string_new("ConsCell"), + "head", head, + "tail", NULL)); +}); + +PURS_FFI_FUNC_2(consList, x, xs, { + return purs_any_record_new( + purs_record_new_from_kvps(3, + "type", purs_any_string_new("ConsCell"), + "head", x, + "tail", xs)); +}); + +PURS_FFI_FUNC_1(listToArray, list, { + purs_vec_t * result = (purs_vec_t *) purs_vec_new(); + purs_any_t * xs = (purs_any_t *) list; + while (xs != NULL) { + const purs_record_t * record = purs_any_get_record(xs); + const purs_any_t * head = purs_record_find_by_key(record, "head")->value; + const purs_any_t * tail = purs_record_find_by_key(record, "tail")->value; + purs_vec_push_mut(result, head); + xs = (purs_any_t *) tail; + } + return purs_any_array_new(result); +}); + +const purs_any_t * buildFrom( + const purs_any_t * apply, + const purs_any_t * map, + const purs_any_t * f, + const purs_any_t * x, + const purs_any_t * ys) { + return purs_any_app( + purs_any_app( + apply, + purs_any_app( + purs_any_app(map, consList$), + purs_any_app(f, x) + ) + ), + ys + ); +} + +const purs_any_t * go( + const purs_any_t * apply, + const purs_any_t * map, + const purs_any_t * f, + const purs_any_t * acc, + const purs_any_int_t currentLen, + const purs_vec_t * xs) { + if (currentLen == 0) { + return acc; + } else { + const purs_any_t * last = xs->data[currentLen - 1]; + const purs_any_t * fn = go(apply, map, f, buildFrom(apply, map, f, last, acc), currentLen - 1, xs); + return purs_any_app(Cont$, fn); + } +} + +PURS_FFI_FUNC_4(Data_Array_NonEmpty_Internal_traverse1Impl, apply, map, f, _array, { + const purs_vec_t * array = purs_any_get_array(_array); + const purs_any_t * acc = purs_any_app( + purs_any_app(map, finalCell$), + purs_any_app(f, array->data[array->length - 1])); + const purs_any_t * result = go(apply, map, f, acc, array->length - 1, array); + while (1) { + if (result -> tag != PURS_ANY_TAG_RECORD) { + break; + } + const purs_record_t * record = purs_any_get_record(result); + const purs_any_t * tp = purs_record_find_by_key(record, "type")->value; + if (purs_any_eq_string(tp, "Cont")) { + result = purs_record_find_by_key(record, "fn")->value; + } else { + break; + } + } + + return purs_any_app(purs_any_app(map, listToArray$), result); +}); diff --git a/src/Data/Array/NonEmpty/Internal.h b/src/Data/Array/NonEmpty/Internal.h new file mode 100644 index 00000000..fcdef01d --- /dev/null +++ b/src/Data/Array/NonEmpty/Internal.h @@ -0,0 +1,9 @@ +#ifndef Data_Array_NonEmpty_Internal_H +#define Data_Array_NonEmpty_Internal_H + +#include + +PURS_FFI_EXPORT(Data_Array_NonEmpty_Internal_fold1Impl); +PURS_FFI_EXPORT(Data_Array_NonEmpty_Internal_traverse1Impl); + +#endif // Data_Array_NonEmpty_Internal_H diff --git a/src/Data/Array/ST.c b/src/Data/Array/ST.c new file mode 100644 index 00000000..1a5a7125 --- /dev/null +++ b/src/Data/Array/ST.c @@ -0,0 +1,115 @@ +#include + +PURS_FFI_FUNC_1(Data_Array_ST_empty, _, { + return purs_any_array_new(purs_vec_new()); +}); + +PURS_FFI_FUNC_5(Data_Array_ST_peekImpl, just, nothing, _i, _xs, _, { + const purs_vec_t * xs = purs_any_get_array(_xs); + const purs_any_int_t i = purs_any_get_int(_i); + if (i >= 0 && i< xs->length) { + return purs_any_app(just, xs->data[i]); + } else { + return nothing; + } +}); + +PURS_FFI_FUNC_4(Data_Array_ST_poke, _i, a, _xs, _, { + purs_vec_t * xs = (purs_vec_t *) purs_any_get_array(_xs); + const purs_any_int_t i = purs_any_get_int(_i); + if (i >= 0 && i < xs->length) { + xs->data[i] = a; + return purs_any_true; + } else { + return purs_any_false; + } +}); + +PURS_FFI_FUNC_3(Data_Array_ST_pushAll, _as, _xs, _, { + purs_vec_t * xs = (purs_vec_t *) purs_any_get_array(_xs); + const purs_vec_t * as = purs_any_get_array(_as); + const purs_any_t * tmp; + purs_any_int_t i; + purs_vec_foreach(as, tmp, i) { + purs_vec_push_mut(xs, tmp); + } + return purs_any_int_new(xs -> length); +}); + +PURS_FFI_FUNC_5(Data_Array_ST_splice, _i, _howMany, _bs, _xs, _, { + const purs_any_int_t i = purs_any_get_int(_i); + const purs_any_int_t howMany = purs_any_get_int(_howMany); + const purs_vec_t * bs = purs_any_get_array(_bs); + purs_vec_t * xs = (purs_vec_t *) purs_any_get_array(_xs); + purs_vec_t * out = (purs_vec_t *) purs_vec_new(); + purs_vec_t * head = (purs_vec_t *) purs_vec_new(); + purs_vec_t * tail = (purs_vec_t *) purs_vec_new(); + const purs_any_t * tmp; + purs_any_int_t j; + purs_vec_foreach(xs, tmp, j) { + if (j >= i) { + if (out->length < howMany) { + purs_vec_push_mut(out, tmp); + } else { + purs_vec_push_mut(tail, tmp); + } + } else { + purs_vec_push_mut(head, tmp); + } + } + purs_vec_reserve(xs, head->length + tail->length + bs->length); + purs_vec_foreach(bs, tmp, j) { + xs->data[head->length + j] = tmp; + } + purs_vec_foreach(tail, tmp, j) { + xs->data[head->length + bs->length + j] = tmp; + } + xs->length = head->length + tail->length + bs->length; + return purs_any_array_new(out); +}); + +PURS_FFI_FUNC_2(Data_Array_ST_copyImpl, _xs, _, { + const purs_vec_t * xs = purs_any_get_array(_xs); + return purs_any_array_new(purs_vec_copy(xs)); +}); + +PURS_FFI_FUNC_3(Data_Array_ST_sortByImpl, comp, _xs, _, { + purs_vec_t * xs = (purs_vec_t *) purs_any_get_array(_xs); + purs_any_int_t i; + purs_any_int_t j; + purs_any_int_t swapped; + const purs_any_t * tmp; + + for (i = 0; i < xs->length-1; i++) { + swapped = 0; + for (j = 0; j < xs->length-i-1; j++) { + const purs_any_t * r = purs_any_app(purs_any_app(comp, xs->data[j]), xs->data[j+1]); + if (purs_any_get_int(r) > 0) { + tmp = xs->data[j]; + xs->data[j] = xs->data[j+1]; + xs->data[j+1] = tmp; + swapped = 1; + } + } + + // IF no two elements were swapped by inner loop, then break + if (swapped == 0) { + break; + } + } + + return purs_any_array_new(xs); +}); + +PURS_FFI_FUNC_2(Data_Array_ST_toAssocArray, _xs, _, { + const purs_vec_t * xs = purs_any_get_array(_xs); + purs_any_int_t i; + const purs_any_t * tmp; + purs_vec_t * out = (purs_vec_t *) purs_vec_new(); + purs_vec_foreach(xs, tmp, i) { + purs_vec_push_mut(out, purs_any_record_new( + purs_record_new_from_kvps(2, "value", tmp, "index", purs_any_int_new(i)) + )); + } + return purs_any_array_new(out); +}); diff --git a/src/Data/Array/ST.h b/src/Data/Array/ST.h new file mode 100644 index 00000000..e01625c7 --- /dev/null +++ b/src/Data/Array/ST.h @@ -0,0 +1,15 @@ +#ifndef Data_Array_ST_H +#define Data_Array_ST_H + +#include + +PURS_FFI_EXPORT(Data_Array_ST_empty); +PURS_FFI_EXPORT(Data_Array_ST_peekImpl); +PURS_FFI_EXPORT(Data_Array_ST_poke); +PURS_FFI_EXPORT(Data_Array_ST_pushAll); +PURS_FFI_EXPORT(Data_Array_ST_splice); +PURS_FFI_EXPORT(Data_Array_ST_copyImpl); +PURS_FFI_EXPORT(Data_Array_ST_sortByImpl); +PURS_FFI_EXPORT(Data_Array_ST_toAssocArray); + +#endif // Data_Array_ST_H diff --git a/src/Data/Array/ST/Partial.c b/src/Data/Array/ST/Partial.c new file mode 100644 index 00000000..011321b2 --- /dev/null +++ b/src/Data/Array/ST/Partial.c @@ -0,0 +1,14 @@ +#include + +PURS_FFI_FUNC_3(Data_Array_ST_Partial_peekImpl, _i, _xs, _, { + const purs_vec_t * xs = purs_any_get_array(_xs); + const purs_any_int_t i = purs_any_get_int(_i); + return xs->data[i]; +}); + +PURS_FFI_FUNC_4(Data_Array_ST_Partial_pokeImpl, _i, a, _xs, _, { + const purs_vec_t * xs = purs_any_get_array(_xs); + const purs_any_int_t i = purs_any_get_int(_i); + xs->data[i] = a; + return NULL; +}); diff --git a/src/Data/Array/ST/Partial.h b/src/Data/Array/ST/Partial.h new file mode 100644 index 00000000..c9fd9032 --- /dev/null +++ b/src/Data/Array/ST/Partial.h @@ -0,0 +1,9 @@ +#ifndef Data_Array_ST_Partial_H +#define Data_Array_ST_Partial_H + +#include + +PURS_FFI_EXPORT(Data_Array_ST_Partial_peekImpl); +PURS_FFI_EXPORT(Data_Array_ST_Partial_pokeImpl); + +#endif // Data_Array_ST_Partial_H diff --git a/test/Test/Data/Array.purs b/test/Test/Data/Array.purs index 53556ac6..d1c59f6a 100644 --- a/test/Test/Data/Array.purs +++ b/test/Test/Data/Array.purs @@ -306,6 +306,9 @@ testArray = do log "groupBy should group consecutive equal elements into arrays based on an equivalence relation" assert $ A.groupBy (\x y -> odd x && odd y) [1, 1, 2, 2, 3, 3] == [nea [1, 1], NEA.singleton 2, NEA.singleton 2, nea [3, 3]] + log "groupBy should be stable" + assert $ A.groupBy (\_ _ -> true) [1, 2, 3] == [nea [1, 2, 3]] + log "nub should remove duplicate elements from the list, keeping the first occurence" assert $ A.nub [1, 2, 2, 3, 4, 1] == [1, 2, 3, 4]