-
Notifications
You must be signed in to change notification settings - Fork 377
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
Add Ord spec #235
Add Ord spec #235
Conversation
README.md
Outdated
A value that implements the Ord specification must also implement | ||
the [Setoid](#setoid) specification. | ||
|
||
1. `a.compare(a) <= 0` (reflexivity) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why <=
rather than ===
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was simply copying the laws from PureScript. No other reason. ===
works just as well and is probably clearer.
README.md
Outdated
1. If `b` is not the same Ord, behaviour of `compare` is | ||
unspecified (returning NaN is recommended). | ||
|
||
2. `compare` must return a number (-1, 0 or 1). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest backticks around -1
, 0
, and 1
(and NaN
). Also, an Oxford comma. ;)
I'm not enamored with the idea of using |
@joneshf what would you suggest? Strings? Symbols? |
Okay here's another formulation:
|
dependencies.png should be regenerated |
How about:
// defined like operators
const lt = (x, y) => x.covers(y);
const gte = (x, y) => !x.covers(y);
const lte = (x, y) => x.covers(y) || x.equals(y);
const gt = (x, y) => !x.covers(y) && !x.equals(y);
const min = (x, y) => x.covers(y) ? x : y;
const max = (x, y) => x.covers(y) ? y : x;
const nativeCompare = (x, y) => x.covers(y) ? -1 : x.equals(y) ? 0 : 1; Edit: |
Back to using
// defined like operators
const equals = (x, y) = x.precedes(y) && y.precedes(x);
const lte = (x, y) => x.precedes(y);
const gt = (x, y) => !x.precedes(y);
const lt = (x, y) => x.precedes(y) && !y.precedes(x);
const gte = (x, y) => !x.precedes(y) || y.precedes(x);
const min = (x, y) => x.precedes(y) ? x : y;
const max = (x, y) => x.precedes(y) ? y : x;
const nativeCompare = (x, y) => !x.precedes(y) ? 1 : y.precedes(x) ? 0 : -1; |
0821ddd
to
86c97e5
Compare
I just changed the formulation to use |
README.md
Outdated
@@ -605,6 +632,11 @@ The `profunctor` method takes two arguments: | |||
When creating data types which satisfy multiple algebras, authors may choose | |||
to implement certain methods then derive the remaining methods. Derivations: | |||
|
|||
- [`equals`][] may be derived from [`precedes`][]: | |||
```js |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Empty line before ```js
, please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
laws/ord.js
Outdated
return eq(a, d) && eq(b, d) && eq(c, d); | ||
}; | ||
|
||
const transitivity = t => eq => x => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of passing t
-s I think we should pass values on which precedes
will be called.
Like just pass f, g, h
instead of t
and x
.
Same in other laws.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I defined precedes
on Id
which may have been wrong as it should just delegate to value
's precedes
. Should I define it in internal/func.js
instead? I could implement it for String
and Number
and delegate otherwise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think yes
Small issue with laws otherwise LGTM. |
Updated with changes to tests. |
Are you happy with this pull request in its current state, @joneshf? If so, let's merge it and release it as v3.2.0. |
❤️ |
I would have assumed Besides naming, I welcome this addition. |
I like @scott-christopher's suggestion. Let's use |
I have a different qualm about naming. The name
I'm fine with either of those options. However, I think we should seriously reconsider it being unspecified currently. |
Thanks for the feedback, Hardy. :)
I don't understand this sentence. What is it that's unspecified? |
I guess nothing, thinking about it. You can infer that it's for partial orderings and not total orderings based on the laws. I think what I should have said was that we should be explicit, rather than saying that something was unspecified 😊. |
I'm in favour of Hardy's second option as I believe the intention was to define the type class of totally ordered sets. Do you agree, @gabejohnson? |
@davidchambers @joneshf that was an oversight on my part. I'll make it a total ordering unless you can think of a reason we wouldn't want to add that constraint. |
@scott-christopher @davidchambers I was looking for a name that didn't suggest quantity and |
I've implemented all of the requested changes. Everything look good? |
index.js
Outdated
@@ -22,7 +22,8 @@ | |||
extend: 'fantasy-land/extend', | |||
extract: 'fantasy-land/extract', | |||
bimap: 'fantasy-land/bimap', | |||
promap: 'fantasy-land/promap' | |||
promap: 'fantasy-land/promap', | |||
lte: 'fantasy-land/lte' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's include this after equals
.
Done. |
README.md
Outdated
- [`equals`][] may be derived from [`lte`][]: | ||
|
||
```js | ||
function (b) { return this.lte(b) && b.lte(this); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency with the other derivations, let's drop the space after function
.
I'd like to see the parameter named other
rather than b
to suggest that the method expects an argument of the same type.
README.md
Outdated
@@ -700,6 +733,7 @@ be equivalent to that of the derivation (or derivations). | |||
[`extract`]: #extract-method | |||
[`map`]: #map-method | |||
[`of`]: #of-method | |||
[`lte`]: #lte-method |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔤
const b = g[lte](f); | ||
const c = true; | ||
return eq(a || b, c); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Taking eq
strikes me as unnecessary. I'd find this clearer:
const totality = a => b => a[lte](b) || b[lte](a);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think all of the laws are like this—equals
included. I can't remember why, but there was a reason we switched to this way of writing the laws.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I.e., it seems fine to me to have these laws work similarly, and revisit whether that's appropriate in another PR. But, if you feel strongly, I won't fight it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that I'm working on fantasyland/fantasy-laws#1, I'd very much like to know the reason. If it occurs to you, let me know. :)
Let's leave this as it is, Gabe. These functions will be removed from this repository in due course.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! I didn't know that existed.
I'll squash as soon as you sign off. |
Let's update the |
Done |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm very excited about this addition! 🌳
@davidchambers do you want me to squash it? |
Yes, it would be nice to squash the commits. :) |
* Use precedes instead of compare to define Ord * Replace reflexivity with totality so we can have a toset * Change 'precedes' to 'lte'
Squashed |
Looks like I forgot to put the link to the new spec in the list here |
No worries. Would you mind opening another pull request? I'll then merge it and release v3.2.0. |
Closes #233
I intentionally left the definition of
Ordering
implicit (as is that ofBoolean
underSetoid
) to spur discussion.I'm looking for any suggestions on a better way to state the laws in both the README and the tests.