Skip to content

Unfoldable.iterate #16

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

Closed
wants to merge 1 commit into from
Closed

Conversation

matthewleon
Copy link
Contributor

following conversation here: #12

@matthewleon
Copy link
Contributor Author

hdgarrood
hdgarrood previously approved these changes Dec 28, 2017
Copy link
Contributor

@hdgarrood hdgarrood left a comment

Choose a reason for hiding this comment

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

Looks great to me, I'd just like to check that adding this dependency isn't going to cause problems before mergig.

@matthewleon
Copy link
Contributor Author

matthewleon commented Dec 28, 2017 via email

@hdgarrood
Copy link
Contributor

hdgarrood commented Dec 28, 2017

Ah right, yes. I wasn't aware we were already pulling it in transitively. In that case I'm happy :) Does anyone else want to comment on this before we merge?

-- | ~~~ purescript
-- | nats = iterate add zero
-- | ~~~
iterate :: forall f a. Unfoldable f => Lazy (f a) => (a -> a) -> a -> f a
Copy link
Contributor

Choose a reason for hiding this comment

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

Why Lazy?

Copy link
Contributor

Choose a reason for hiding this comment

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

To clarify, Lazy is neither necessary nor sufficient for this function to work correctly.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you expand on that?

Copy link
Contributor

Choose a reason for hiding this comment

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

Well, the condition we want is for unfoldr to work with inputs which never return Nothing, but that has nothing to do with Lazy. It's just a coincidence that this works for both list types, but I can think of certain cyclic structures which are not lazy but for which this function is okay. This function doesn't use the constraint, so it's easy to construct something which is Lazy but for which the function fails.

Copy link
Contributor

@hdgarrood hdgarrood Dec 30, 2017

Choose a reason for hiding this comment

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

Can you give an example of one of these cyclic structures? I'm not quite sure what that means.

Come to think of it, do you think there's a way of using defer to make this safe? I suppose not, since it really depends on how the specific Unfoldable instance implements unfoldr? If we did defer \_ -> unfoldr (...), like #12 originally had, I guess that wouldn't really do it either, as unfoldr might still try to force the entire structure..?

Also, the Lazy class doesn't seem to be particularly clearly defined at the moment (Pursuit); do you think it might be possible to clarify when it's acceptable to define an instance?

Copy link
Contributor

Choose a reason for hiding this comment

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

Right, of course. I think in this case it's not really possible to say whether that instance is law-abiding, because the definition of Unfoldable is not sufficiently clear.

I wonder if it might be possible to clearly define what we mean by "appended" by adding a Foldable constraint to this class, and saying that after "appending" something, it must appear in the result list when converting to a list using Foldable. That is, if we let x :: a and define

f cond = if cond
  then Just (Tuple x false)
  else Nothing

then we should have that x `elem` toList (unfoldr f true)? Are there any useful Unfoldable instances which are not Foldable?

Copy link
Contributor Author

@matthewleon matthewleon Dec 30, 2017

Choose a reason for hiding this comment

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

(an aside, I feel persuaded to drop the Lazy constraint at this point. Still curious about the cyclical strict structures though.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

probably worth moving the law discussion to a separate issue?

Copy link
Contributor

@hdgarrood hdgarrood Dec 30, 2017

Choose a reason for hiding this comment

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

Or perhaps better, for an instance Unfoldable f, let xs :: List a, and then we should have:

case List.last xs of
  Just x -> x `List.elem` toList (List.toUnfoldable xs :: f a)
  Nothing -> true

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, probably is at this point.

@hdgarrood hdgarrood dismissed their stale review December 30, 2017 03:15

Seems like this needs a little further discussion.

@JordanMartinez
Copy link
Contributor

I haven't read through this entire thread since it has a long comment thread and references other issues/PRs.

It's been a while since this PR has seen activity. I'm also not sure how many people would actually use this. Should this be closed? Or should we try to finish it?

-- | nats = iterate add zero
-- | ~~~
iterate :: forall f a. Unfoldable f => (a -> a) -> a -> f a
iterate f = unfoldr (\x -> Just (Tuple x (f x)))
Copy link
Contributor

@JordanMartinez JordanMartinez Sep 23, 2021

Choose a reason for hiding this comment

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

Note: this function never terminates, so it only works on lazy structures. In other words, I'm pretty sure this would stack overflow:

iterate add zero :: Array Int

@JordanMartinez
Copy link
Contributor

I'm in favor of closing this PR for the reason expressed in the above comment.

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.

4 participants