-
Notifications
You must be signed in to change notification settings - Fork 41
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
Rewrite #41
Conversation
docs/spec.md
Outdated
@@ -113,20 +96,30 @@ For example: | |||
- Two promises are equivalent when they yield equivalent values. | |||
- Two functions are equivalent if they yield equivalent outputs for equivalent inputs. | |||
|
|||
Note that these examples are not universal, in some cases differnet |
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.
s/differnet/different/
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.
Thanks!
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.
Appologies for the splattering of comments, but I thought I'd go through the spec and offer a few suggestions, primarily in how the types are presented in code.
README.md
Outdated
Specification for common algebraic types in JavaScript | ||
based on [Fantasy Land](https://github.com/fantasyland/fantasy-land). | ||
Specification for common algebraic structures in JavaScript | ||
based on [fantasy-land](https://github.com/fantasyland/fantasy-land). |
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.
The spec's name is actually spelt "Fantasy Land".
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.
Yeah, I'm going back and forth with this. I like how lower case "static-land" looks (except in titles), but if I use lower case "static-land" then "Fantasy Land" next to it looks off.
README.md
Outdated
|
||
In Static Land a type is just a collection of static functions, and instances | ||
In static-land we use static functions, and instances |
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.
In static-land, we use ...
Note the added comma.
README.md
Outdated
|
||
Simply expose some [Type Objects](docs/spec.md#type) that work with types that your library provides or with types defined in another library or with native types like Array. | ||
Simply expose some [module](docs/spec.md#module) that work with types that your library provides or with types defined in another library or with native types like Array. |
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.
Simply expose
somea module ...
Note the edit.
@@ -1,104 +1,87 @@ | |||
# Static Land Specification |
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.
You should either change this to "static-land specification" or change all the instances of "static-land" elsewhere to "Static Land", for consistency. Otherwise, it looks very off.
docs/spec.md
Outdated
@@ -1,104 +1,87 @@ | |||
# Static Land Specification | |||
|
|||
This is a specification for common algebraic types in JavaScript based on | |||
[Fantasy Land Specification](https://github.com/fantasyland/fantasy-land). | |||
This specification describes JavaScript interfaces and 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.
Try something like this:
This specification describes a set of JavaScript interfaces and algebraic laws that are common in some other functional languages like Haskell.
I feel this could also be improved, but I think you might see what I'm getting at.
Foldable<T> { | ||
reduce: ((a, b) => a, a, T<b>) => 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.
Maybe this?
interface Foldable<T<*>> {
reduce: ((a, b) => a, a, T<b>) => a;
}
Extend<T> { | ||
extend: (T<a> => b, T<a>) => T<b> | ||
} | ||
``` |
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.
Maybe this?
interface Extend<T<*>> {
extend: (T<a> => b, T<a>) => T<b>;
}
|
||
#### Methods | ||
```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.
Maybe this?
interface Comonad<T<*>> extends Functor<T>, Extract<T> {
extract: (T<a>) => a;
}
docs/spec.md
Outdated
|
||
#### Methods | ||
In the following signature `Applicative<U>` means that a value must | ||
not only match `Applicative` signature, but also fully support `Applicative` algebra. |
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.
How about this? Probably not optimal, but it's a little more specific, and ties to my suggestion below.
In the following signature,
U<*> extends Applicative<U>
means that values of that type must be modules that both implement theApplicative
signature and follow its laws.U
itself represents the type of such values.
Traversable<T> { | ||
traverse: (Applicative<U>, a => U<b>, T<a>) => U<T<b>> | ||
} | ||
``` |
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.
Maybe this?
interface Traversable<T<*>, U<*> extends Applicative<U>>
extends Functor<T>, Foldable<T> {
traverse: (U, a => U<b>, T<a>) => U<T<b>>;
}
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.
Here U
is a function level variable, we don't want to make it signature level variable. There is an important distinction:
Also notice that signature level type variables are fixed for a module, while a function level variable can be substituted with a different concrete type in each function application. In other words we must choose what T stands for when we create a module, and we must choose what a stands for only when we apply baz to some value.
Although maybe U
should be lower case then 🤔
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.
Then this?
interface Traversable<T<*>>
extends Functor<T>, Foldable<T> {
traverse: <U<*> extends Applicative<U>>(U, a => U<b>, T<a>) => U<T<b>>;
}
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.
This doesn't seem right. U<*> extends Applicative<U>
suggest that U
is a module, then a => U<b>
and U<T<b>>
are wrong, these functions are not returning modules.
To clarify, in my current version U
is a type like Array
, e.g. if second argument of traverse()
is a function that returns arrays, then first argument must be a module that supports Applicative
with T=Array
.
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.
To clarify, I mean U
represents the module, but U<a>
is an instance. Similarly, Maybe
is a type class, and Maybe a
is an instance's type.
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.
Yeah, I understand your point of view. I just don't think we should use a module name as a type name. If I have a module called Maybe
, the values it's working with won't be automatically of types Maybe<number>
, Maybe<boolean>
etc. It could use arrays for example under the hood ([1]
for some, and []
for nothing), so the values that module works with would be of family of types Array<something>
. Or it could be working with instances of class Maybe {...}
then, values would have types Maybe<something>
after all, but that name "Maybe" will refer to a class name, not to a module name.
This way of thinking seems more correct to what we're dealing with. Modules are not types. In principal some methods of a module can work with different types from another. Or we even may have an algebra which signature parametrized with two or more types.
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.
Btw, current version of the spec calls modules "types", that was a mistake, and to fix it was the initial inspiration for this rewrite 🙃
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 now starting to see why you use Applicative<U>
instead - the value's type would be Maybe<T>
, while the module type would be Monad<Maybe<T>>
. So I'll go with 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.
Well because in notation that I made up Applicative<U>
in that position means "a module that matches Applicative
signature for type U
" :)
Check out section that describes the notation.
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.
Yeah. I caught that, but I didn't read it as such. I'd read it as "a module that implements Applicative<U>
for type U
".
Ok, I'm going to merge this. Thanks for help @isiahmeadows and @polytypic ! |
Fixes #32
Fixes #34
Fixes #9