-
Notifications
You must be signed in to change notification settings - Fork 102
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 First
documentation
#195
Conversation
1 similar comment
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 not smart enough yet to comment on all the types and functionality, but I did what I could.
src/First/README.md
Outdated
`First` is a `Monoid` that will always return the first, non-empty value when | ||
(2) `First` instances are combined. `First` is able to be a `Monoid` because | ||
it implements a `Maybe` under the hood. The use of the `Maybe` allows for an | ||
empty to be represented with a `Nothing`. |
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.
What is "an empty"? Should this be "an empty _________ " (thing) or is "empty" supposed to be the thing we're talking about?
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.
an empty First
. Say nothing meets the "criteria" like say an empty array when using mconcat
, or if we are using Maybe
to check a condition an neither of the values meet the criteria then there is no First
to return, resulting in an empty First
(First( Nothing )
).
Basically for something to be a Monoid
is must have a value the represents idenity for the operation in that anything concat
-ed to the identity (or empty) will result in the same value. So First(3).concat(First.empty())
results in First( Just 3 )
as does First.empty().concat(First(3))
Any suggestions on how I can communicate that in this paragraph without too much theory?
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 doing two things could really clear this up for beginners (like me!) and one thing applied everywhere at a later date could make the docs more accessible to beginners:
empty
in the sentence sounds like a descriptor, so maybe usingempty 'First'
would help to clarify it- it doesn't have to include theory -- you can show values in a small example. I'm not sure if I'm doing these right, but here we go:
First.empty() // => First( Nothing )
First(3) // => First( Just 3 )
First(3).concat(First.empty()) // => First( Just 3 )
First.empty().concat(First(3)) // => First( Just 3 )
- separately, all the category theory and ADTs are awesome for people that are familiar, but it'd also be potentially useful to point to the fantasy land spec or wikipedia or articles or something the first time a term is used in any doc.
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 like everything about this and think I can address these like this:
- Add just like you suggest with empty
First
instance in the cases I speak about empty instance. - As the examples as described are shown in the
empty
static function, so what do you think about me adding a link to#empty
where I have the word empty? - So I think that the docs could benefit from a section on basic category theory, typeclasses and signatures may address the reference issue.
Do you think that will do 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.
A link to the empty
function would be real nice.
With regards to 3.
: if there are solid resources out there that can be linked to or copied+pasted+cited to handle this, then I would advise not recreating the wheel. However, if this could increase the accessibility and understanding of the project more than external links could and can provide more of a community benefit, then that's a noble thing if you have the time. Heck, maybe the docs get turned into a book.
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, but then you HAVE to maintain those links and you if you cite, it is very difficult without bringing in other citations as context and sometime that context needs context.
I woulds rather curate my own docs and tie them to crocks
. Give me more control over context.
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.
Makes sense
src/First/README.md
Outdated
`First` can be constructed with either a value or a `Maybe` instance. Any value | ||
passed to the constructor will be wrapped in a `Just` to represent a non-empty | ||
instance of `First`. Any `Maybe` passed to the constructor will be lifted as | ||
is, allowing the ability to "choose" an value based on some disjunction. |
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.
an value
or a value
?
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.
a value
src/First/README.md
Outdated
|
||
chooseFirst([ 21, 45, 2, 22, 19 ]) | ||
.valueOf(0) | ||
//=> Just 2 |
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 example
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.
Except it is misleading, valueOf
takes no arguments
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 WONDERING ABOUT THAT. I mean the example as a whole 🤕
#### concat | ||
|
||
```haskell | ||
First a ~> First a -> First 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 might be brainfreezing – what does the ~>
(tilde-arrow) signify?
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.
That signifies an instance in which the given method is executed on, so this reads:
When called on an Instance of First a
, give me a First a
and I will give back a First a
.
src/First/README.md
Outdated
|
||
`concat` is used to combine (2) `Semigroup`s of the same type under an operation | ||
specified by the `Semigroup`. In the case of `First`, it will always provide the | ||
first non-empty value. Any subsequent non-empty values will be thrown away, and |
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.
don't need a comma here as no new subject?
src/First/README.md
Outdated
``` | ||
|
||
`First` wraps an underlying `Maybe` which provides the ability to option out | ||
a value in the case as of an empty instance. Just like `option` on a `Maybe` |
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.
is the as
needed here? think it works fine as ...to option out a value in the case of an empty instance
src/First/README.md
Outdated
instance, it takes a value as its argument. When run on an empty instance, | ||
the provided default will be returned. If `option` is run on a non-empty | ||
instance however, the wrapped value will be extracted not only from the | ||
`Last`, but also from the underlying `Just`. |
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.
don't think comma needed
src/First/README.md
Outdated
``` | ||
|
||
Used to transform a given `Either` instance to a `First` | ||
instance, `eitherToFirst` will turn a `Right` instance into a non-empty `First` |
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.
comma after First
I think?
src/First/README.md
Outdated
wrapping the original value contained in the `Right`. All `Left` instances will | ||
map to an empty `First`, mapping the originally contained value to a `Unit`. | ||
Values on the `Left` will be lost and as such this transformation is considered | ||
lossy in that regard. |
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.
Is lossy
an understood term? Should you be linking to an article or definition or something? Never heard this term in this context, myself, but I'm a noob...
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 use the term from Information Theory for source coding, on some encodings, for things like say a bitmap to a jpeg. I do not have an isomorphism from bitmap -> jpeg and jpeg -> bitmap and have them point back to the same exact bitmap on the round trip.
Same thing happens here, because Either
has both Left
and Right
and the target First
maps all Lefts
to Unit
, I can never get back to the same Left
as I started with, without providing some value to map the Unit
back into the original Left
.
So I do not know if it is an equivalent term, but could not come up with one that is quite so close.
Do you have any suggestions on how I could make this more clear to the curious?
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.
A link to something on the subject is always a nice thing to have.
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.
Since this occurs any time we have a transformation with most sum types to Maybe
, it will end up being a common theme.
So I think that primer I mentioned a couple times could have a section on natural transformations with Sum Types.
But in the meantime, how would you feel about emphasizing this point in the code example with a comment over this line to the effect of:
// 'Bad Times' is lost
eitherToFirst(Left('Bad Times'))
//=> First( Nothing )
Will also do the same with resultToFirst
.
Do you think that may help?
@rpearce your questions are making me think that a brief "primer" on some basic category theory, type signatures and typeclasses may be in order. What do you think about something like that? |
Looks like I was able to address (for the most part), the provided feedback.
|
First things is First
This PR addresses another item on this issue and adds the README for the
First
Monoid. Before the next release (2) other READMEs will be added, one forAsync
and another forLast
. Once all (3) are merged, we will move them over to the overall docs.This PR addresses the
First
item on this issue