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

type of Z.of #3

Closed
davidchambers opened this issue Sep 24, 2016 · 5 comments
Closed

type of Z.of #3

davidchambers opened this issue Sep 24, 2016 · 5 comments

Comments

@davidchambers
Copy link
Member

What's the appropriate type of Z.of? There appear to be two options:

of :: Applicative f => (f a, b) -> f b
of :: Applicative f => ({ fantasy-land/of :: a -> f a }, b) -> f b

The advantage of the first option is that given Applicative f => f a we can find the of function in either of the valid locations:

typeof x['fantasy-land/of'] === 'function' ? x['fantasy-land/of']
                                           : x.constructor['fantasy-land/of']

With the second option the caller would need to do this work:

Z.of(typeof x['fantasy-land/of'] === 'function' ? x : x.constructor, 42)

We shouldn't optimize for the case in which we already have a value of the type, though. After all, the purpose of of is to allow us to create values of the type so we shouldn't need to create a value of the type in order to create a value of the type! Thus the second option seems more sensible. Do others agree?

Whatever we decide here should determine the type of Z.chainRec as well. Z.empty is a different matter because an empty method is strictly more powerful than an empty function (though this will no longer apply if and when fantasyland/fantasy-land#164 is merged).

@safareli
Copy link
Member

safareli commented Sep 25, 2016

What if we could represent actual Type (Maybe for example) in the Signature, like this:

//    safeFoldMap :: (ChainRec F, Monoid F, Applicative F) => F -> SomeStructure a -> F a
// or 
//    safeFoldMap :: (ChainRec F, Monoid F, Applicative F) => F _ -> SomeStructure a -> F a
const safeFoldMap = (F, x) => {
   ...
   // here we can call F.chainRec, F.of, F.empty
   ...
   return res
}

safeFoldMap(Maybe, data);

I have also commented of FL#164 about this idea

@davidchambers
Copy link
Member Author

That would be very nice, @safareli, but the FL spec doesn't require Type values such as S.Maybe to exist. Everything in the spec is written from the perspective of a member of a type. So we need to accept a type dictionary, but we don't know where such a dictionary will come from. It could be Foo itself, or Foo.prototype, or Foo.of(42), or new Foo(42).

I think the spec should require a Type value to be defined. of, empty, and chainRec should be defined on the Type value (and nowhere else), and each member of the type should have a fantasy-land/type property which points to the Type value. Then a function such as Z.of could simply require a Type value as an argument.

@Bradcomp
Copy link
Member

I agree. It makes the most sense for the type dictionary to exist on the type itself, and not on the instances directly (although it could also be both if somebody chose to implement it that way).

I like signature 2. I don't think it should be implied that an instance is already needed in order to create an instance.

@davidchambers
Copy link
Member Author

I've updated #2. Please have a look at the change and let me know your thoughts. :)

@safareli
Copy link
Member

safareli commented Oct 3, 2016

👍 looks good!

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

3 participants