Skip to main content
Elaborated on point #2, as asked in a comment.
Source Link
Toxaris
  • 396
  • 1
  • 3

Could the fold approach have worked? If so, how?

intersperse' i = foldr (\x ys -> x : if null ys then [] else i : ys) []

In the fold, we cannot access the rest of the input, only the rest of the output. However, if and only if the input was empty, the output will be empty. So null ys happens to works here.

Interesting aspects:

  1. I changed the argument order to match the standard intersperse. This happens to work better with the foldr-based definition. More importantely, I feel that intersperse is more often partially applied with an element than with a list, so the element should go first.

  2. I use foldr instead of foldl to increase laziness and avoid the accumulator construction. Note how I don't need acc ++ [x] because I only add elements to the front of lists.

  3. I make sure that intersperse' produces the first (:) cell before the null check.

Could the fold approach have worked? If so, how?

intersperse' i = foldr (\x ys -> x : if null ys then [] else i : ys) []

In the fold, we cannot access the rest of the input, only the rest of the output. However, if and only if the input was empty, the output will be empty. So null ys happens to works here.

Interesting aspects:

  1. I changed the argument order to match the standard intersperse. This happens to work better with the foldr-based definition. More importantely, I feel that intersperse is more often partially applied with an element than with a list, so the element should go first.

  2. I use foldr instead of foldl to increase laziness and avoid the accumulator construction.

  3. I make sure that intersperse' produces the first (:) cell before the null check.

Could the fold approach have worked? If so, how?

intersperse' i = foldr (\x ys -> x : if null ys then [] else i : ys) []

In the fold, we cannot access the rest of the input, only the rest of the output. However, if and only if the input was empty, the output will be empty. So null ys happens to works here.

Interesting aspects:

  1. I changed the argument order to match the standard intersperse. This happens to work better with the foldr-based definition. More importantely, I feel that intersperse is more often partially applied with an element than with a list, so the element should go first.

  2. I use foldr instead of foldl to increase laziness and avoid the accumulator construction. Note how I don't need acc ++ [x] because I only add elements to the front of lists.

  3. I make sure that intersperse' produces the first (:) cell before the null check.

Source Link
Toxaris
  • 396
  • 1
  • 3

Could the fold approach have worked? If so, how?

intersperse' i = foldr (\x ys -> x : if null ys then [] else i : ys) []

In the fold, we cannot access the rest of the input, only the rest of the output. However, if and only if the input was empty, the output will be empty. So null ys happens to works here.

Interesting aspects:

  1. I changed the argument order to match the standard intersperse. This happens to work better with the foldr-based definition. More importantely, I feel that intersperse is more often partially applied with an element than with a list, so the element should go first.

  2. I use foldr instead of foldl to increase laziness and avoid the accumulator construction.

  3. I make sure that intersperse' produces the first (:) cell before the null check.