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

Add First documentation #195

Merged
merged 3 commits into from
Jan 31, 2018
Merged

Add First documentation #195

merged 3 commits into from
Jan 31, 2018

Conversation

evilsoft
Copy link
Owner

@evilsoft evilsoft commented Jan 28, 2018

First things is First

image

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 for Async and another for Last. Once all (3) are merged, we will move them over to the overall docs.

This PR addresses the First item on this issue

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 9252f2e on first-docs into 48a1439 on master.

1 similar comment
@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 9252f2e on first-docs into 48a1439 on master.

@coveralls
Copy link

coveralls commented Jan 28, 2018

Coverage Status

Coverage remained the same at 100.0% when pulling 42c83ce on first-docs into 48a1439 on master.

Copy link
Contributor

@rpearce rpearce left a 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.

`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`.
Copy link
Contributor

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?

Copy link
Owner Author

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?

Copy link
Contributor

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:

  1. empty in the sentence sounds like a descriptor, so maybe using empty 'First' would help to clarify it
  2. 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.

Copy link
Owner Author

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:

  1. Add just like you suggest with empty First instance in the cases I speak about empty instance.
  2. 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?
  3. 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?

Copy link
Contributor

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.

Copy link
Owner Author

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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense

`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.
Copy link
Contributor

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?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a value


chooseFirst([ 21, 45, 2, 22, 19 ])
.valueOf(0)
//=> Just 2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice example

Copy link
Owner Author

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

Copy link
Contributor

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
Copy link
Contributor

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?

Copy link
Owner Author

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.


`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
Copy link
Contributor

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?

```

`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`
Copy link
Contributor

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

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`.
Copy link
Contributor

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

```

Used to transform a given `Either` instance to a `First`
instance, `eitherToFirst` will turn a `Right` instance into a non-empty `First`
Copy link
Contributor

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?

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.
Copy link
Contributor

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...

Copy link
Owner Author

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?

Copy link
Contributor

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.

Copy link
Owner Author

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?

@evilsoft
Copy link
Owner Author

@rpearce your questions are making me think that a brief "primer" on some basic category theory, type signatures and typeclasses may be in order.
Maybe I should extend the getting started section to address this.

What do you think about something like that?

@evilsoft
Copy link
Owner Author

Looks like I was able to address (for the most part), the provided feedback.
Will follow up with an issue to add Guides for the following:

  • typeclasses (Monoids, Alts, Functors, etc)
  • type signatures
  • Natural Transformations

@evilsoft
Copy link
Owner Author

image

@evilsoft evilsoft merged commit 60a482b into master Jan 31, 2018
@evilsoft evilsoft deleted the first-docs branch January 31, 2018 01:09
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

Successfully merging this pull request may close these issues.

3 participants