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

Cofoldable #53

Open
joneshf opened this issue Jan 4, 2014 · 3 comments
Open

Cofoldable #53

joneshf opened this issue Jan 4, 2014 · 3 comments

Comments

@joneshf
Copy link
Member

joneshf commented Jan 4, 2014

As mentioned here I'd like to propose a Cofoldable. There's detailed information about it here

The idea is that while Foldable and Cofoldable are lawless alone, together you can suggest some laws on them.

It should have one of two methods:

  • fromArray :: [a] -> f a
  • unfold

I'm actually unsure on the definition of unfold Should it be (a -> b -> b) -> b -> b -> f a as in the definition for `build in the link, or something else? In any case, one can be derived from the other.

Please discuss.

@DrBoolean
Copy link

There's an Unfoldable package that gives some guidance here:
http://hackage.haskell.org/package/unfoldable-0.8.1/docs/Data-Unfoldable.html
It even provides fromList

Regarding #7, it seems like Cofoldable makes sense over Unfoldable if the whole purpose is to provide some laws. Although in that case, my opinion is that we're being really specific about a natural transformation or isomorphism.

Anyways, for unfold:

Since this is fantasy land, I think we should use Option to flag the end of the unfold rather than a guard fn or null.

Array's instance could be:

//+ unfold :: (b -> Option([a, b])) -> b -> [a]
Array.prototype.unfold = function(step, seed) {
  var output = this;
  return step(seed).cata({
    Some: function(result) {
      return output.concat(result[0]).unfold(step, result[1]);
    },
    None: function() {
      return output;
    }
  });
}

var result = [].unfold(function(x){ return (x > 10) ? None : Some([x, x+1]); }, 0)
console.log(result);

@SimonRichardson
Copy link
Member

👍 on using Option instead of a guard func & null.
Looks nice and clean to me.

@safareli
Copy link
Member

safareli commented Sep 18, 2016

Just an idea: chainRec of Array could be used as unfold

Array.chainRec(function(next, done, x) {
  return (x == 10) ? [done(x)] : [done(x), next(x+1)]
}, 0) // [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]

// implementation of Array.chainRec
function stepNext(x) { return {value: x, done: false }; }
function stepDone(x) { return {value: x, done: true }; }

Array.chainRec = function _chainRec(f, i) {
  var todo = [i];
  var res = [];
  var buffer, xs, idx;
  while (todo.length > 0) {
    xs = f(stepNext, stepDone, todo.shift());
    buffer = [];
    for (idx = 0; idx < xs.length; idx += 1) {
      (xs[idx].done ? res : buffer).push(xs[idx].value);
    }
    Array.prototype.unshift.apply(todo, buffer);
  }
  return res;
};

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

No branches or pull requests

4 participants