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

It's easy to silently mess up Stream.flatMap calls #176

Open
ceedubs opened this issue Sep 6, 2023 · 1 comment
Open

It's easy to silently mess up Stream.flatMap calls #176

ceedubs opened this issue Sep 6, 2023 · 1 comment

Comments

@ceedubs
Copy link
Contributor

ceedubs commented Sep 6, 2023

This is a fun one that I just ran into. What is the result of this watch expression?

> Stream.fromList ["foo", "bar"]
    |> Stream.flatMap (s -> Stream.fromList (toCharList s))
    |> Stream.toList!

If you guessed [] then you are right!

The issue is that the code should use Stream.fromList! (toCharList s) instead of Stream.fromList (toCharList s).

Let's look at the signature of Stream.flatMap:

  Stream.flatMap :
    (a ->{e, Stream b} any) -> '{e, Stream a} r -> '{e, Stream b} r

In the example, the function that we are passing in has the signature Char -> {} ('{Stream Char} ). So Stream.flatMap views this as a function that takes a Char, doesn't emit any stream elements, and then returns an ignored value which happens to be a thunk that would emit a stream of characters should you run it instead of ignore it.

I think that a simple solution would be to make Stream.flatMap require () as the return type of the mapping function:

  Stream.flatMap :
    (a ->{e, Stream b} ()) -> '{e, Stream a} r -> '{e, Stream b} r

This means that occasionally you might need to add an ignore to your function, but I think that's a small price to pay to avoid silent issues that cause your code to not at all do what you would expect.

NOTE: the same applies to Stream.flatMap!.

cc @anovstrup who has done a lot of great Stream work.

@ceedubs
Copy link
Contributor Author

ceedubs commented Sep 6, 2023

Hah I now retract my "Sounds fine to me" that I commented here.

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

No branches or pull requests

1 participant