summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/ur/list.ur26
-rw-r--r--lib/ur/list.urs4
-rw-r--r--tests/groupBy.ur3
-rw-r--r--tests/groupBy.urp4
4 files changed, 22 insertions, 15 deletions
diff --git a/lib/ur/list.ur b/lib/ur/list.ur
index eac5ab0c..50764e46 100644
--- a/lib/ur/list.ur
+++ b/lib/ur/list.ur
@@ -435,29 +435,29 @@ fun drop [a] (n : int) (xs : list a) : list a =
fun splitAt [a] (n : int) (xs : list a) : list a * list a =
(take n xs, drop n xs)
-fun span [a] (f:(a -> bool)) (ls:list a) : list a * list a =
+fun span [a] (f : a -> bool) (ls : list a) : list a * list a =
let
- fun span' f acc ls =
+ fun span' ls acc =
case ls of
[] => (rev acc, [])
- | x :: xs => if (f x) then span' f (x :: acc) xs else (rev acc, ls)
+ | x :: xs => if f x then span' xs (x :: acc) else (rev acc, ls)
in
- span' f [] ls
+ span' ls []
end
-fun groupBy [a] (f:(a -> a -> bool)) (ls:list a) : list (list a) =
+fun groupBy [a] (f : a -> a -> bool) (ls : list a) : list (list a) =
let
- fun groupBy' f ls =
+ fun groupBy' ls acc =
case ls of
- [] => [] :: []
+ [] => rev ([] :: acc)
| x :: xs =>
- let
- val (ys, zs) = span (f x) xs
- in
- (x :: ys) :: (groupBy' f zs)
- end
+ let
+ val (ys, zs) = span (f x) xs
+ in
+ groupBy' zs ((x :: ys) :: acc)
+ end
in
- groupBy' f ls
+ groupBy' ls []
end
fun mapXiM [m ::: Type -> Type] (_ : monad m) [a] [ctx ::: {Unit}] (f : int -> a -> m (xml ctx [] [])) : t a -> m (xml ctx [] []) =
diff --git a/lib/ur/list.urs b/lib/ur/list.urs
index ac874d7c..432d8c1a 100644
--- a/lib/ur/list.urs
+++ b/lib/ur/list.urs
@@ -106,8 +106,8 @@ val drop : t ::: Type -> int -> list t -> list t
val take : t ::: Type -> int -> list t -> list t
val splitAt : t ::: Type -> int -> list t -> list t * list t
-(** Longest prefix of elements, which satisfy a predicate *)
+(** Longest prefix of elements that satisfy a predicate, returned along with the remaining suffix *)
val span : a ::: Type -> (a -> bool) -> t a -> t a * t a
-(** Group a list *)
+(** Group a list into maximal adjacent segments where all elements compare as equal, according to the provided predicate. *)
val groupBy : a ::: Type -> (a -> a -> bool) -> t a -> t (t a)
diff --git a/tests/groupBy.ur b/tests/groupBy.ur
new file mode 100644
index 00000000..e91e33cc
--- /dev/null
+++ b/tests/groupBy.ur
@@ -0,0 +1,3 @@
+val main : transaction page = return <xml><body>
+ {[List.groupBy eq (1 :: 1 :: 2 :: 2 :: 3 :: 4 :: 4 :: 4 :: 5 :: [])]}
+</body></xml>
diff --git a/tests/groupBy.urp b/tests/groupBy.urp
new file mode 100644
index 00000000..de1db792
--- /dev/null
+++ b/tests/groupBy.urp
@@ -0,0 +1,4 @@
+rewrite all GroupBy/*
+
+$/list
+groupBy