Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stdlib: add List.intersperse and List.intercalate #9962

Closed
wants to merge 1 commit into from

Conversation

craigfe
Copy link
Contributor

@craigfe craigfe commented Oct 7, 2020

Adds a new function – List.intersperse : 'a -> 'a list -> 'a list – to the standard library. This transforms a list l by adding a separating element between each adjacent pair of elements in l. For example:

# List.intersperse 0 [1; 2; 3] ;;
- : int list = [1; 0; 2; 0; 3]

# List.intersperse 0 [] ;;
- : int list = []

I re-define this function reasonably often, and it's slightly annoying to do so due to the asymmetry of the empty list case. Example use-cases I've had in the past:

  • adding comma / tab separators to a list representing .csv / .tsv fields;
  • adding yield points to a list of computations;
  • adding "spacing" elements to a DSL term (for file separators, break hints, etc.).

Notes:

  • Other standard libraries that include this function: Jane Street base, Haskell base and Elm core.

  • If intersperse is deemed useful, I think there's a strong argument for (at least) Seq.intersperse as well. I'm happy to add that to this PR.

Copy link
Contributor

@nojb nojb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some general comments. I don't have a strong opinion on whether to include this or not in the stdlib; let's wait for other developers to chime in.

stdlib/list.ml Outdated
@@ -87,6 +87,10 @@ let rec flatten = function

let concat = flatten

let rec intersperse sep = function
| ([] | [ _ ]) as l -> l
| x :: (_ :: _ as xs) -> x :: sep :: intersperse sep xs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably better to make the function tail-recursive.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done 🙂

stdlib/list.mli Outdated
@@ -128,6 +128,13 @@ val flatten : 'a list list -> 'a list
(length of the argument + length of the longest sub-list).
*)

val intersperse : 'a -> 'a list -> 'a list
(** [intersperse sep l] is the list formed by inserting [sep] between adjacent
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not go further and allow the separator to be a 'a list?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 'a -> 'a list -> 'a list form has a more descriptive type and I think more intuitively matches the name "intersperse".

Anecdotally, I've never found I needed the more general form either. YMMV.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I'm not sure I had that much of a need for intersperse (but I don't mind). I rather often missed the signature of String.concat for List (which would be 'a list -> 'a list list -> 'a list).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dbuenzli: Interesting. I've never found a need for that one, but I know Haskell developers like it, and they call it intercalate. I'm happy to add that along with this PR if it's deemed worthy; it's in some sense the natural sibling to intersperse.

@craigfe craigfe force-pushed the list-intersperse branch 2 times, most recently from 42442c4 to 04f9a8e Compare October 8, 2020 13:01
@craigfe craigfe force-pushed the list-intersperse branch 2 times, most recently from a946fde to 1022881 Compare January 3, 2021 16:42
@craigfe craigfe changed the title stdlib: add List.intersperse stdlib: add List.intersperse and List.intercalate Jan 3, 2021
@craigfe
Copy link
Contributor Author

craigfe commented Jan 3, 2021

Rebased and added List.intercalate as per @dbuenzli's suggestion.

@damiendoligez
Copy link
Member

You should investigate the CI failures.

I don't have a strong opinion on adding these functions. Maybe @gasche or @alainfrisch would like to comment?

@craigfe craigfe force-pushed the list-intersperse branch 2 times, most recently from 9e8655c to 501710c Compare May 20, 2021 15:21
@craigfe
Copy link
Contributor Author

craigfe commented May 20, 2021

AppVeyor is now green. A maintainer will need to explicitly approve triggering the other CIs (thanks to GitHub's new security policy).

@craigfe craigfe force-pushed the list-intersperse branch 2 times, most recently from 09adbf7 to 24e765f Compare May 20, 2021 19:10
@dbuenzli
Copy link
Contributor

dbuenzli commented Mar 17, 2022

Still missing that fun. Btw. I'm not sure I see the interest of adding intersperse once you have intercalate

@Hirrolot
Copy link
Contributor

Hirrolot commented Dec 8, 2022

What's the status of this issue? I need interleave quite often. You can also find it in the standard library of Haskell and in libraries extending OCaml std, such as containers.

@nojb
Copy link
Contributor

nojb commented Dec 14, 2022

What's the status of this issue? I need interleave quite often. You can also find it in the standard library of Haskell and in libraries extending OCaml std, such as containers.

The status is that the PR is stalled. Judging from the discussion, there wasn't a lot of support for the addition, nor was there strong opposition. There was some related discussion in #10583 (comment).

Again judging from the discussion, there does not seem to be a lot of consensus about which signaturess are the most useful in practice.

In any case, I think any addition in this direction should be done in both List and Seq simultaneusly, and evaluated accordingly.

@Hirrolot
Copy link
Contributor

@nojb, I can make another PR that borrows code from this PR and introduces the same functions for List and Seq simultaneously, and then we can re-evaluate it. How does that sound?

@nojb
Copy link
Contributor

nojb commented Dec 15, 2022

@nojb, I can make another PR that borrows code from this PR and introduces the same functions for List and Seq simultaneously, and then we can re-evaluate it. How does that sound?

No opposition in principle.

@craigfe craigfe closed this Dec 17, 2022
@craigfe
Copy link
Contributor Author

craigfe commented Dec 17, 2022

Closed as I don't have the bandwidth to un-stall this at the moment. Best of luck with the follow-up PR @Hirrolot :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants