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

$.RecordType should also return a curried data constructor #66

Closed
davidchambers opened this issue May 8, 2016 · 5 comments
Closed

$.RecordType should also return a curried data constructor #66

davidchambers opened this issue May 8, 2016 · 5 comments

Comments

@davidchambers
Copy link
Member

@kedashoe, in sanctuary-js/sanctuary#206 (comment):

Only loosely related to this PR, but it would be cool if $.RecordType returned a constructor/type rather than just a type.

const Point = $.RecordType({x: Number, y: Number});
S = S.create(true, S.env.concat([Point]));
let p = Point(10, 20);

I think this would also help sanctuary-def know that it actually received a type rather than just some StrMap if the keys are homogenous?

I've found myself doing this quite often:

//    $Repository :: Type
const $Repository = $.RecordType({
  origin: $.String,
  username: $.String,
  name: $.String,
  tagPrefix: $.String,
});

//    Repository :: String -> String -> String -> String -> Repository
const Repository =
def('Repository',
    {},
    [$.String, $.String, $.String, $.String, $Repository],
    unapply(zipObj(['origin', 'username', 'name', 'tagPrefix'])));

It would be very cool to be able to define a record type and a curried function for creating values of that type in one go. We could achieve this by having $.RecordType return a (type, constructor) tuple or by having it return a value which serves both roles, as Kevin suggested. The latter has the advantage of avoiding naming collisions and the awkward type names—such as $Repository—they entail.

Are we willing to rely on object enumeration order? If so, we could have $.RecordType continue to provide the current, elegant API. If not, we're forced to have it take a list of pairs:

//    Repository :: Type
const Repository = $.RecordType([
  ['origin', $.String],
  ['username', $.String],
  ['name', $.String],
  ['tagPrefix', $.String],
]);

I could live with this, though I would miss the correspondence between the shape of the type definition and the shape of values of that type. Perhaps a better solution is to rely on object enumeration order and clearly document this assumption.

@davidchambers
Copy link
Member Author

I think this would also help sanctuary-def know that it actually received a type rather than just some StrMap if the keys are homogenous?

@kedashoe, could you explain what you meant by this?

@kedashoe
Copy link
Member

kedashoe commented May 8, 2016

Not sure when I'll be in front of a proper computer next, so I'll just respond now from memory as best I can..

First of all I don't think the end of that sentence makes any sense, so I'm not sure anyone can explain it :) But I think I was doing something like this

//    id :: a -> a
const id = a => return 10;
const $Point = $.RecordType({x: Number, y: Number});
let Point = function(x, y) { this.x = x; this.y = y };
let p = new Point(1, 2);
id(p);

and the error message was telling me my StrMap was wrong (that code probably doesn't quite make sense, basically I was just forcing a typevar conflict). What I was trying to say here was maybe there would be a way to construct p such that sanctuary-def could tell me my Point was wrong rather than my StrMap?

@davidchambers
Copy link
Member Author

I think I see what you're getting at, Kevin (but correct me if I'm wrong). You're wanting to create a value of type { x :: Number, y :: Number } with metadata attached which says that such values are known as points. You'd like to see Point in error messages rather than { x :: Number, y :: Number }. This was proposed by @Wideshanks in #7.

In the post-#55 era we'd lose a lot by displaying name only.

color :: { color :: String, position :: { x :: Number, y :: Number } } -> String
                                               ^^^^^^

The above would become:

color :: ColorPoint -> String
         ^^^^^^^^^^

@kedashoe
Copy link
Member

kedashoe commented May 9, 2016

I was hoping for

Point( x :: 1, y :: 2 )

but yes, I think you've got the idea (and not critical to this issue, just loosely related)

@davidchambers
Copy link
Member Author

This is out of scope for sanctuary-def.

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

2 participants